Random socket error 10054

Removed…See post below for details

Ok guys,

If anyone is willing to give this a try. Below is the minimal code for both the cobra and a windows console application. The console application send a request to the cobra (just a string) and the cobra responds with “CobraReply”. Nothing fancy at all. This simple setup gives me random socket errors 10054 (An existing connection was forcibly closed by the remote host)

If someone can try this on their Cobra and post the results here I would be thankful. Even better would be if someone can find the cause of this error.

Code for the Cobra:


///References added:
///FEZCobra_GHIElectronics.NETMF.FEZ
///Microsoft.SPOT.Hardware
///Microsoft.SPOT.Native
///mscorlib
///System

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using Socket = System.Net.Sockets.Socket;

namespace FEZ_Cobra_SocketServer_Test
{
	public class Program
	{
		public static void Main()
		{
			SocketServer ss = new SocketServer();

			Thread.Sleep(Timeout.Infinite);
		}
	}

	public class SocketServer
	{
		public SocketServer()
		{
			// Create a socket, bind it to the server's port, and listen for client 
			// connections.
			Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 12000);
			server.Bind(localEndPoint);
			server.Listen(Int32.MaxValue);

			while (true)
			{
				// Wait for a client to connect.
				Socket clientSocket;
				try
				{
					clientSocket = server.Accept();
				}
				catch (SocketException se)
				{
					Debug.Print("Error: " + se.Message);
					return;
				}

				// Process the client request.  true means asynchronous.
				new ProcessClientRequest(clientSocket, true);
			}
		}

		/// <summary>
		/// Processes a client request.
		/// </summary>
		internal sealed class ProcessClientRequest
		{
			private Socket m_clientSocket;

			/// <summary>
			/// The constructor calls another method to handle the request, but can 
			/// optionally do so in a new thread.
			/// </summary>
			/// <param name="clientSocket"></param>
			/// <param name="asynchronously"></param>
			public ProcessClientRequest(Socket clientSocket, Boolean asynchronously)
			{
				m_clientSocket = clientSocket;

				if (asynchronously)
					// Spawn a new thread to handle the request.
					new Thread(ProcessRequest).Start();
				else ProcessRequest();
			}

			/// <summary>
			/// Processes the request.
			/// </summary>
			private void ProcessRequest()
			{
				const Int32 c_microsecondsPerSecond = 1000000;

				m_clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, -2);

				// 'using' ensures that the client's socket gets closed.
				using (m_clientSocket)
				{
					// Wait for the client request to start to arrive.
					Byte[] buffer = new Byte[1024];
					if (m_clientSocket.Poll(5 * c_microsecondsPerSecond, SelectMode.SelectRead))
					{
						// If 0 bytes in buffer, then the connection has been closed, 
						// reset, or terminated.
						if (m_clientSocket.Available == 0)
						{
							Debug.Print("ClientSocket Available = 0");
							return;
						}
						// Read the first chunk of the request
						try
						{
							Int32 bytesRead = m_clientSocket.Receive(buffer, m_clientSocket.Available, SocketFlags.None);
						}
						catch (SocketException se)
						{
							Debug.Print("Error: " + se.Message);
							return;
						}
						string reply = "CobraReply";
						byte[] buf = new byte[Encoding.UTF8.GetBytes(reply).Length];
						buf = Encoding.UTF8.GetBytes(reply);
						m_clientSocket.Send(buf, 0, buf.Length, SocketFlags.None);
						m_clientSocket.Close();

					}
				}
			}
		}
	}
}


Code for the windows console app: (to end, just press a key)


///References added:
///System.Net

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication_Socket_Test
{
	class Program
	{
		static void Main(string[] args)
		{
			Timer requestTimer = new Timer(new TimerCallback(RequestTimer_tick), null, 0, 2000);
			Console.ReadKey();
		}

		static void RequestTimer_tick(object o)
		{
			SocketClient.Send("test");
		}
	}

	public class SocketClient
	{
		private static string message { get; set; }
		public static string clientip { get; set; }
		public static int clientport { get; set; }

		private static int numRecvs;
		private static int numErrors;

		/// <summary>
		/// Send string to remote server (Cobra)
		/// </summary>
		/// <param name="txt">The string</param>
		public static void Send(string txt)
		{
			message = txt;
			clientip = "10.0.10.123"; //change this to the IP address of the cobra set with MFDeploy
			clientport = 12000;
			SendMessage();
		}


		/// <summary>
		/// Sends the message
		/// </summary>
		private static void SendMessage()
		{
			const Int32 c_microsecondsPerSecond = 1000000;

			// Create a socket connection to the specified server and port.
			using (Socket serverSocket = ConnectSocket(clientip, clientport))
			{
				if (serverSocket != null)
				{
					// Send request to the server.
					Byte[] bytesToSend = Encoding.UTF8.GetBytes(message + "\r\n");
					serverSocket.Send(bytesToSend, bytesToSend.Length, SocketFlags.None);

					//// Reusable buffer for receiving chunks of the document.
					Byte[] buffer = new Byte[4096];

					// Poll for data until 5-second timeout.  Returns true for data and 
					// connection closed.
					while (serverSocket.Poll(5 * c_microsecondsPerSecond, SelectMode.SelectRead))
					{
						// If there are 0 bytes in the buffer, then the connection is 
						// closed, or we have timed out.
						if (serverSocket.Available == 0)
							break;

						// Zero all bytes in the re-usable buffer.
						Array.Clear(buffer, 0, buffer.Length);

						// Read a buffer-sized HTML chunk.
						serverSocket.ReceiveBufferSize = 2048;
						int numberOfBytesRead = 0;
						int totalNumberOfBytes = 0;
						try
						{
							do
							{
								numberOfBytesRead = serverSocket.Receive(buffer, totalNumberOfBytes, serverSocket.ReceiveBufferSize, SocketFlags.None);
								totalNumberOfBytes += numberOfBytesRead;
							}
							while (numberOfBytesRead > 0);
							numRecvs++;
						}
						catch (SocketException se)
						{

							Console.WriteLine(string.Format("{0} Socket Error code {1}, exeption: {2}",DateTime.Now.TimeOfDay , se.ErrorCode, se.Message));
							numErrors++;
							return;
						}

						byte[] formatedBytes = new byte[totalNumberOfBytes];
						for (int i = 0; i < totalNumberOfBytes; i++)
						{
							formatedBytes[i] = buffer[i];
						}

						string test = new String(Encoding.UTF8.GetChars(formatedBytes));
						Console.WriteLine(string.Format("{0} Bytes received:{1}, success:{3}, errors:{4}, Message:{2}",DateTime.Now.TimeOfDay, totalNumberOfBytes, test, numRecvs, numErrors));
					}
				}
				else
				{
				}
			}
		}

		/// <summary>
		/// Creates a socket and uses the socket to connect to the server's IP 
		/// address and port.
		/// </summary>
		/// <param name="server">Server IP Address</param>
		/// <param name="port">Server Port Number</param>
		/// <returns>Server socket</returns>
		private static Socket ConnectSocket(String server, Int32 port)
		{
			try
			{
				// Create socket and connect to the server's IP address and port
				Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
				socket.Connect(new IPEndPoint(IPAddress.Parse(clientip), port));
				return socket;

			}
			catch (Exception)
			{
				return null;
			}
		}
	}
}


I let this run over night and these are the results:

Request sent: 13611
Replies received: 10780
Socket Errors (it’s only 10054): 2831

That’s a error rate of 20%, or in other words, 80% of the requests receive a reply.
Something has to be wrong.

GHI, any idea what is wrong or what I might ne doing wrong?

Greetings

no clue

Did you try to capture what is happening on the network using a protocol analyser, such as Wireshark ? It may give you some clues at what is wrong ?

I solved the problem and here’s what I think happened.

Many months ago I was working on another project with network sockets and posted the problem on the forum. I was running fast out of the 128 available sockets and I believe Mike told me to disable the lingering of sockets. Since then I kept on using the linger option.

Now my listening socket is inside a using block and you would expect that the using takes care of cleaning up the socket. It does indeed cleanup, but not fast enough. So after I removed the linger option and close the socket explicitly inside the using block, all started working fine without errors and without running out of sockets.

You can’t imagine how hard I banged my head against the wall the past days :o

Anyway, for future reference, Even if you open a socket inside a using block, make sure you close the socket when you’re done with it. (and don’t set the linger option).

Greetings to all