Click here to Skip to main content
15,888,297 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have created socket program in C# console application using Asynchronous Server Socket. I referred example from below site to listen to particular port on server. https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.100).aspx

My application code is.

C#
static void Main(string[] args)
      {
          Process thisProc = Process.GetCurrentProcess();
          StartListening();
      }

      public static void StartListening()
      {
          // Data buffer for incoming data.
          byte[] bytes = new Byte[iSize];

          // Establish the local endpoint for the socket.
          // The DNS name of the computer
          // running the listener is "host.contoso.com".
          IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
          IPAddress ipAddress = ipHostInfo.AddressList[0];
          IPEndPoint localEndPoint = new IPEndPoint( ipAddress , Convert.ToInt32 (ConfigurationSettings.AppSettings["Port"].ToString()));

          // Create a TCP/IP socket.
          Socket listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
          Console.WriteLine("Waiting for a connection on..." +  ConfigurationSettings.AppSettings["Port"].ToString());
          // Bind the socket to the local endpoint and listen for incoming connections.
          try
          {
              listener.Bind(localEndPoint);
              listener.Listen(1000);

              while (true)
              {
                  // Set the event to nonsignaled state.
                  allDone.Reset();

                  // Start an asynchronous socket to listen for connections.

                  listener.BeginAccept(
                      new AsyncCallback(AcceptCallback),
                      listener);

                  // Wait until a connection is made before continuing.
                  allDone.WaitOne();
              }

          }
          catch (Exception e)
          {
              writeToLogFile(string.Format("Client {0}\t StartListening Exception ={1}", DateTime.Now.ToString() + ": ", e.Message + " Stack=" + e.StackTrace), "E");
          }

          Console.WriteLine("\nPress ENTER to continue...");
          Console.Read();

      }

      public static void AcceptCallback(IAsyncResult ar)
      {
          // Signal the main thread to continue.
          try
          {
              allDone.Set();

              // Get the socket that handles the client request.
              Socket listener = (Socket)ar.AsyncState;
              Socket handler = listener.EndAccept(ar);

              // Create the state object.
              StateObject state = new StateObject();
              StateRecord++;
              handler.ReceiveTimeout = 0;
              handler.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
              state.workSocket = handler;
              //state.BufferSize = iSize;
              if (handler != null)
              {
                  state.IP = ((IPEndPoint)handler.RemoteEndPoint).Address;
                  state.port = ((IPEndPoint)handler.RemoteEndPoint).Port;
              }

              Thread jobFile3 = new Thread(delegate() { writeToLogFile(string.Format("Client {0}{1} {2}\t Connected", DateTime.Now + ": " + state.IP, ":", state.port ), "E"); });
              jobFile3.Start();

              handler.BeginReceive(state.buffer, 0, iSize, 0, new AsyncCallback(ReadCallback), state);
          }

          catch (Exception e)
          {

              Thread jobFileEx = new Thread(delegate() { writeToLogFile(string.Format("Client {0}\t socket Exception at AcceptCallback ={1}", DateTime.Now.ToString() + ": " , e.Message + " Stack=" + e.StackTrace), "E"); });
              jobFileEx.Start();
          }
      }

      public static void ReadCallback(IAsyncResult ar)
      {

          try
          {
              // Retrieve the state object and the handler socket from the asynchronous state object.
              StateObject state = (StateObject)ar.AsyncState;
              Socket handler = state.workSocket;
              string ipAdd = state.IP.ToString();
              string portNo = state.port.ToString();

              // Read data from the client socket.
              SocketError errorCode;
              int bytesRead = handler.EndReceive(ar, out errorCode);

              if (state.Record == 1 && bytesRead == 0 && state.MaxTry <= 3) // If 0 data received initially then retry to get data
              {
                  state.MaxTry++;
                  Thread.Sleep(500);
                  handler.BeginReceive(state.buffer, 0, iSize, 0, new AsyncCallback(ReadCallback), state);
              }
              else if (bytesRead > 0)
              {
                  // There  might be more data, so store the data received so far.

                  string Recd = state.Record.ToString();
                  StringBuilder ByteData = new StringBuilder();
                  foreach (byte byt in state.buffer)
                  {
                      ByteData.Append(byt.ToString() + ",");
                  }
                  string SaveByteData = ByteData.ToString();

                  Thread jobFile3 = new Thread(delegate() { writeToLogFile(string.Format("Client {0}{1} {2}\t Length = {3}/{4}", DateTime.Now + ": " + ipAdd, ":", portNo, bytesRead, Recd + " Data=" + SaveByteData), "E"); });
                  jobFile3.Start();

                  Thread job = new Thread(delegate() { SaveMetaData(SaveByteData, ipAdd, portNo); });
                  job.Start();

                  state.Record++;
                  //Send(handler, "*");

                  handler.BeginReceive(state.buffer, 0, iSize, 0, new AsyncCallback(ReadCallback), state);

                  // Echo the data back to the client.

              }
              else
              {

                  if (( errorCode == SocketError.TimedOut || errorCode == SocketError.ConnectionReset ) && state.MaxTry <= 3 )
                  {
                      state.MaxTry++;

                      Thread.Sleep(100);
                      handler.BeginReceive(state.buffer, 0, iSize, 0, new AsyncCallback(ReadCallback), state);
                  }

                  if (handler != null && handler.Connected)
                  {
                      handler.Shutdown(SocketShutdown.Both);
                      handler.Close();
                      StateRecord--;
                  }

                  Thread jobFile = new Thread(delegate() { writeToLogFile(string.Format("Client {0}{1} {2}\t Disconnected,  Status = {3}", DateTime.Now + ": " + ipAdd, ":", portNo, errorCode.ToString() + " byteRead=" + bytesRead + " Total Client =" + StateRecord), "E", true); });
                  jobFile.Start();

                  if (StateRecord > 25)
                  {
                      StateRecord = 20;
                      GC.Collect();
                      GC.WaitForPendingFinalizers();
                      GC.Collect();
                  }
              }
          }

          catch (Exception e)
          {
              StateObject state = (StateObject)ar.AsyncState;
              string ipAdd = state.IP.ToString();
              string portNo = state.port.ToString();
              Socket handler = state.workSocket;

              if (handler != null && handler.Connected)
              {
                  handler.Shutdown(SocketShutdown.Both);
                  handler.Close();
                  StateRecord--;
              }

              Thread jobFileEx = new Thread(delegate() { writeToLogFile(string.Format("Client {0}\t socket Exception ={1}", DateTime.Now.ToString() + ": " + ipAdd + ": " + portNo, e.Message + " Stack=" + e.StackTrace), "E"); });
              jobFileEx.Start();
          }
      }


My client is device (like vehicle tracking device) which sends data periodically using AT command through GPRS service. Most of the time data received on server by my console application but some time data not received by my application.

When data send by device it gets reply "Send OK" from SIM card but my console application on server doesn't receive any thing.

I have checked client, server communication using wireshark utility which is network analyzer tool. We monitor the port & found some times ACK between client & server is missing. This data is received on wireshark but not on c# console application.

Can you please let us know what setting I missed in program or on server ?
Please refer screen of captured TCP data. Here 216 is our server IP & device IP is 106.
http://i.stack.imgur.com/WOjjs.png[^]
Posted
Updated 12-Oct-15 0:32am
v2

1 solution

Inside the method
C#
public static void ReadCallback(IAsyncResult ar)
you have a local variable string SaveByteData.

Shouldn't this variable be declared outside the method in order to actually keep the data if it comes in chunks?

Also, how do you know that it is the end of one transmission?
Do you have an ETX character or end string or similar?
 
Share this answer
 
Comments
sushiljadhav 12-Oct-15 7:40am    
Thanks for reply George. We are retrieving data using BeginReceive() where iSize is of length 15. So we always get 15 bytes data. So used variable SaveByteData to store 15 byte information & then passed it for database storage.

If there is no data (0 byte) return by bytesRead then we consider it as end of records & close the socket connection.
int bytesRead = handler.EndReceive(ar, out errorCode);
George Jonsson 12-Oct-15 7:44am    
OK. It was a lot of code to go through, so I missed that part.
sushiljadhav 12-Oct-15 7:48am    
Anything else i need to check from server end or from application ? or any reference site. We are working on this from long time but no solution. :(
George Jonsson 12-Oct-15 8:14am    
One thing that is weird is that EndReceive returns with 0 data.
MSDN states "The EndReceive method will block until data is available", so you should have some data to read.
Maybe you can check the SocketError if bytesRead = 0.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900