why won't ethernet stay connected for more than a few hours?

Try something like this. I modified the code to read the server response until the server closes the connection, then closes this end. That should allow the socket to close properly and avoid running out of sockets.

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress server(74,125,39,104); // Google

EthernetClient client;
String formkey = "MyFormKey";

void setup(){
 // start the serial library:
  Serial.begin(57600);
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
}

void loop(){

  // detect state of connection 
  Serial.print("checking connection . . . ");
  if (client.connect(server, 80)) {
    Serial.println("connected!");
    Serial.println("Posting . . . ");
    
    String data;
  data="entry.0.single=";
  data+=analogRead(A2);
  data+="&submit=Submit";

    client.print("POST /formResponse?formkey=");
    client.print(formkey);
    client.println("&ifq HTTP/1.1");
    client.println("Host: spreadsheets.google.com");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.println("Connection: close");
    client.print("Content-Length: ");
    client.println(data.length());
    client.println();
    client.print(data);

    Serial.print("POST /formResponse?formkey=");
    Serial.print(formkey);
    Serial.println("&ifq HTTP/1.1");
    Serial.println("Host: spreadsheets.google.com");
    Serial.println("Content-Type: application/x-www-form-urlencoded");
    Serial.println("Connection: close");
    Serial.print("Content-Length: ");
    Serial.println(data.length());
    Serial.println();
    Serial.print(data);
    Serial.println();
    Serial.println("Posted!");

    Serial.println("client returned: ");

    while(client.connected()) {
      while(client.available()) {
        Serial.write(client.read());
      }
    }
    client.stop();
    Serial.println();
    Serial.println("disconnected");
  }
  else {
    Serial.println("failed");
  }

  delay(20000);
}

My apology in advance for any typos or errors.

edit: I forgot the "failed" message print, so I added it. The code above does not include a timeout, and may lock up in the "while(client.connected())" loop if the connection breaks (fails, not closes, like pulling the cat5 cable out of the shield). If this works for you, let me know and I will post the timeout modification.

...and I removed that form key from my post, in the event that is your real form key.