Here's the latest code I used for pachube on a device I haven't posted about yet.
void sendPachubeData(){
 char dataBuf[100];
Â
 if(pachube.connected()) // already trying to get data, just leave
  return;
 if(round(realPower) == 0.0) // don't send invalid data
  return;
 tNow = now();
 strcpy_P(Dbuf2,PSTR("Data at %02d:%02d:%02d: ")); // Debugging
 sprintf(Dbuf,Dbuf2,hour(tNow),minute(tNow),second(tNow));
//Â Serial.print(Dbuf);
 // construct the data buffer so we know how long it is
 int poolMotorState = 0;
 if(strcmp(poolData.motorState,"High") == 0)
  poolMotorState = 2;
 else if(strcmp(poolData.motorState,"Low") == 0)
  poolMotorState = 1;
 strcpy_P(Dbuf2, PSTR("%d,%d,0.%d,%d.%02d,%d.%02d,%d.%02d,%d,%d,%d,%d"));
 sprintf(dataBuf,Dbuf2,
  (int)round(realPower),
  (int)round(apparentPower),
  (int)(powerFactor*100),
  (int)rmsCurrent,
  (int)(((rmsCurrent+0.005) - (int)rmsCurrent) * 100),
  (int)rmsVoltage,
  (int)(((rmsVoltage+0.005) - (int)rmsVoltage) * 100),
  (int)(frequency),
  (int)(((frequency+0.005) - (int)frequency) * 100),
  (ThermoData[0].currentTemp + ThermoData[1].currentTemp)/2,
  (int)round(outsideTemp),
  poolMotorState, poolMotorState == 0 ? 10 : poolData.poolTemp);
 Serial.println(dataBuf);
//return;
 strcpy_P(Dbuf,PSTR("Pachube Connecting..."));
 Serial.print(Dbuf);
 if(pachube.connect()){
  strcpy_P(Dbuf,PSTR("OK"));
  Serial.println(Dbuf);
  tNow = now();
  strcpy_P(Dbuf,PSTR("PUT /api/9511.csv HTTP/1.1\n"));
  pachube.print(Dbuf);
  strcpy_P(Dbuf,PSTR("Host: www.pachube.com\n"));
  pachube.print(Dbuf);
  strcpy_P(Dbuf,PSTR("X-PachubeApiKey: stuffinhere\n"));
  pachube.print(Dbuf);
  strcpy_P(Dbuf,PSTR("Content-Length: "));
  pachube.print(Dbuf);
  pachube.println(strlen(dataBuf), DEC); // this has to be a println
  strcpy_P(Dbuf,PSTR("Content-Type: text/csv\n"));
  pachube.print(Dbuf);
  strcpy_P(Dbuf,PSTR("Connection: close\n"));
  pachube.println(Dbuf);
  pachube.println(dataBuf);Â
  pachube.stop();
  pachubeUpdateTime = now();
 }
 else {
  pachube.stop();
  while(pachube.status() != 0){
   delay(5);
  }
  strcpy_P(Dbuf,PSTR("failed"));
  Serial.println(Dbuf);
 }
}
This works every time the actual board is working. I also have code around the ethernet board itself to make sure it is working that is separate from this stuff. For example, this is the code to reset the ethernet board:
void ethernetReset(){
 pinMode(rxSense, INPUT); //for stabilizing the ethernet board
 pinMode(ethernetResetPin,INPUT);
 while(1){
  digitalWrite(ethernetResetPin, HIGH);
  pinMode(ethernetResetPin, OUTPUT);
  digitalWrite(ethernetResetPin, LOW); // ethernet board reset
  delay(100);
  digitalWrite(ethernetResetPin, HIGH);
  delay(5000);
  // now, after the reset, check the rx pin for constant on
  if (ethernetOk())
   return;
  delay(100);
 }
}
Keep in mind that this depends on the hardware mods I did to the board so that I can reset it separately from the rest. Since I'm using an arduino 2560 that has the watchdog timer bug in the boot loader I can't do a regular watchdog reset. I use one of the timer interrupts instead and do a call to address 0 to reset the board. That took some time to figure out.
I also have a little routine that I call that watches the RX led on the ethernet board. It seems in my case that when the board hangs up the RX led is solid on. So I hooked a wire to it and watch it with an arduino pin. If the led is on too many times in a timing loop, it means the board is hung up. So I use the reset routine above to reset it.
boolean ethernetOk(){
 int cnt = 10, result;
 cnt = 10;
 result = 0;
 while (cnt-- != 0){ // simply count the number of times the light is on in the loop
  result += digitalRead(rxSense);
  delay(50);
 }
 strcpy_P(Dbuf,PSTR("Ethernet setup result "));
 Serial.print(Dbuf);
 Serial.println(result,DEC);
 if (result >=6)   // experimentation gave me this number YMMV
  return(true);
 return(false);
}
Like your experience, I found that one MUST close the connections or the darn thing hangs up. I guess I was extremely lucky to have it fail immediately so that I had to work up solutions before I started relying on it.
On the new device that updates pachube, there is still one problem I have to deal with. Sometimes pachube itself stops responding and I have trouble telling if it was pachube messing up or the ethernet board failing. I'm still thinking about that problem and suspect it will be easy to fix by just checking the pachube response for 'OK' and also looking at some of the other web interactions the board is doing to see if they are working ok. If all else fails, I'll just interogate my router to see if it's alive. That way I can just wait for pachube to come back up. I've had this problem three times now which is not bad for several months of data transmission.
One other thing I want to mention is that I use the TimeAlarms library to time the updates to pachube instead of counting milliseconds or something like that. I set an alarm to fire every so often and just go do other stuff as necessary keeping the values I want to send to pachube updated. This way I don't have anything hanging me up because Ijust let the alarm fire and it takes care of that kind of thing for me. This trick allows me to have a display that steps through the various values and little LEDs that tell me what is going on at a glance. I am using the TimeAlarm libray as a task controller and then just set up the various tasks.
Too much information???