No Socket Available error with Wifi Shield

When I run the example sketch to repeatedly make a request on a web server, I get the dreaded No Socket Available error after 4-5 connections.

I've seen this issue addressed elsewhere (like here: http://forum.arduino.cc/index.php/topic,170460.0.html), but those solutions do not fix my problem.

Can anyone point me in the right direction? I upgraded the firmware on the WiFi shield and I run Arduino 1.0.5

Thank you in advance.

If you are using the wifi shield as a client, and the connection fails, it eats a socket. Four fails and it is over. It is an error in the wifi library. The cause and fix is here:

You would also need to close the connection after successful requests, in order to free up the socket. The board only supports four simultaneous sockets, so If the first four requests are succeeding and the rest fail that implies that you aren't closing the client socket correctly.

Hi,
this is Marco from florence-italy

are only two weeks since I entered in the fantastic (but hard) world of arduino

I'm trying to send data to Emoncms.org, but I've the same problem of this topic
I made the corrections to the library as suggested by surfertim, and I read all the other topics about this, but I could not solve the problem yet...

I use a mac with Arduino IDE 1.0.6 and I've just upgraded the wifishield firmware to vs 1.1.0

this is my code

/*
  Arduino & OpenEnergyMonitor 
  
  This sketch connects to an emoncms server and makes a request using
  Arduino Ethernet shield (or other based on Wiznet W5100) or an 
  Arduino Wifi Shield
  
  author Mirco Piccin aka pitusso
  
  based on 
  http://arduino.cc/en/Tutorial/WebClientRepeating
*/

char foo;  //without a simple variable declaration, use of #ifdef at the top of your code raises an error!

//if using a W5100 based Ethernet shield, comment out the following line; 
//leave untouched if using Arduino Wifi Shield
#define WIFI

#include <SPI.h>

#ifdef WIFI
  #include <WiFi.h>
  #include <WiFiClient.h>
#else
  #include <Ethernet.h>
#endif

// Include Emon Library
#include "EmonLib.h"                   

//network configuration, WIRED or WIFI
#ifdef WIFI
  //if using WIFI 
  char ssid[] = "xxxxxx"; //  your network SSID (name) 
  char pass[] = "xxxxxxx";    // your network password (use for WPA, or use as key for WEP)

  int status = WL_IDLE_STATUS;
  int keyIndex = 0;            // your network key Index number (needed only for WEP)
  
  WiFiClient client;
#else
  //if using WIRED
  byte mac[] = {0x90, 0xA2, 0xDA, 0xOF, 0x91, 0x46};
  
  // fill in an available IP address on your network here,
  // for auto configuration:
  IPAddress ip(192, 168, 1, 2);
  IPAddress subnet(255, 255, 255, 0);
  IPAddress DNS(8, 8, 8, 8);
  IPAddress gw(192, 168, 1, 254);
  
  EthernetClient client;
#endif

//Calibrations
const int volt = 228;
const float ct_calibration = 27.5;
const float temp_offset = 3.54;

// Sensor pins
const int tempSensorPin = A0;
const int lightSensorPin = A1;
const int currentSensorPin = A2;

float tempValue = 0;
float Irms = 0;
int lightValue = 0;

// Create an Emon instance
EnergyMonitor emon1;                   

//Emoncms configurations
char server[] = "emoncms.org";     // name address for emoncms.org
//IPAddress server(213, 138, 101, 177);  // numeric IP for emoncms.org (no DNS)

String apikey = "xxxxxxx";  //api key
int node = 0; //if 0, not used

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000;  // delay between updates, in milliseconds

void setup() {
  // start serial port:
  Serial.begin(9600);

  // Display a welcome message
  Serial.println("Emoncms client starting...");

  emon1.current(currentSensorPin, ct_calibration);

#ifdef WIFI
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 
  
  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. 
    status = WiFi.begin(ssid, pass);
  
    // wait 10 seconds for connection:
    delay(10000);
  } 
  Serial.println("Connected to wifi");
#else
  if (!Ethernet.begin(mac)) {
    // if DHCP fails, start with a hard-coded address:
    Serial.println("Failed to get an IP address using DHCP, forcing manually");
    Ethernet.begin(mac, ip, dns, gw, subnet);
  }
#endif  

  printStatus();
}

void loop() {
  
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("Disconnecting...");
    client.stop();
  }
  
  // if you're not connected, and at least <postingInterval> milliseconds have
  // passed sinceyour last connection, then connect again and
  // send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
   
    //read sensors
    lightValue = analogRead(lightSensorPin);
    tempValue = getCelsius(analogRead(tempSensorPin));
    Irms = emon1.calcIrms(1480);
    
    //Print values (debug)
    Serial.println();
    Serial.print("Temp : ");
    Serial.print(tempValue);
    Serial.print(" ; Light : ");
    Serial.print(lightValue);
    Serial.print(" ; Power : ");
    Serial.println(Irms*volt);
      
    //send values
    sendData();
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:
void sendData() {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("Connecting...");
    // send the HTTP GET request:
    client.print("GET /api/post?apikey=");
    client.print(apikey);
    if (node > 0) {
      client.print("&node=");
      client.print(node);
    }
    client.print("&json={temp");
    client.print(":");
    client.print(tempValue + temp_offset);    
    client.print(",light:");
    client.print(lightValue);
    client.print(",power:");
    client.print(Irms*volt);   
    client.println("} HTTP/1.1");
    client.println("Host:emoncms.org");
    client.println("User-Agent: Arduino-ethernet");
    client.println("Connection: close");
    client.println();

    // note the time that the connection was made:
    lastConnectionTime = millis();
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("Connection failed");
    Serial.println("Disconnecting...");
    client.stop();
  }
}


void printStatus() {
  #ifdef WIFI
    // print the SSID of the network you're attached to:
    Serial.print("SSID: ");
    Serial.println(WiFi.SSID());

    // print your WiFi shield's IP address:
    IPAddress ip = WiFi.localIP();
    Serial.print("IP Address: ");
    Serial.println(ip);

    // print the received signal strength:
    long rssi = WiFi.RSSI();
    Serial.print("signal strength (RSSI):");
    Serial.print(rssi);
    Serial.print(" dBm");
  #else
    // print your local IP address:
    Serial.print("IP address: ");
    for (byte thisByte = 0; thisByte < 4; thisByte++) {
      // print the value of each byte of the IP address:
      Serial.print(Ethernet.localIP()[thisByte], DEC);
      Serial.print("."); 
    } 
  #endif
  Serial.println();
}

float getCelsius(int sensorValue) {
/*
  created by Federico Vanzati for TinkerKit Thermistor Library
*/
  const static float ADCres = 1023.0;
  const static int Beta = 3950;			// Beta parameter
  const static float Kelvin = 273.15;	// 0°C = 273.15 K
  const static int Rb = 10000;			// 10 kOhm
  const static float Ginf = 120.6685;	// Ginf = 1/Rinf 
  
  float Rthermistor = Rb * (ADCres / sensorValue - 1);
  float _temperatureC = Beta / (log( Rthermistor * Ginf )) ;
  return _temperatureC - Kelvin;
}

can someone help me?

This is the function I added to my sketches to troubleshoot the wifi shield problems. Call this function before every connection attempt to see if there is a socket available.

#include <utility/server_drv.h>

void ShowSockStatus() {
  for(int x = 0; x < MAX_SOCK_NUM; x++) {
    Serial.print(WiFi._state[x]);    
    Serial.print("  ");
    Serial.print(WiFi._server_port[x]);    
    Serial.print("  s=");
    Serial.print(serverDrv.getServerState(x));    
    Serial.print("  c=");
    Serial.print(serverDrv.getClientState(x));    
    Serial.print("  d=");
    Serial.println(serverDrv.availData(x));    
 }
}

Thanks for the prompt answer!

but....where should I put this code exactly?

ps: sorry but I do not have a lot of experience in programming