Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# socket
Hi, I have the following Sockets server, which works asynchronously and
accepts multiple clients connected at once. I got it from the microsoft
website.
I made slight modifications in the example code, in the configuration of
the IPAddress and port.
1. using System;
   2. using System.Net;
   3. using System.Net.Sockets;
   4. using System.Text;
   5. using System.Threading;
   6.  
   7. // State object for reading client data asynchronously
   8. public class StateObject
   9. {
  10.     // Client  socket.
  11.     public Socket workSocket = null;
  12.     // Size of receive buffer.
  13.     public const int BufferSize = 1024;
  14.     // Receive buffer.
  15.     public byte[] buffer = new byte[BufferSize];
  16.     // Received data string.
  17.     public StringBuilder sb = new StringBuilder();
  18. }
  19.  
  20. public class AsynchronousSocketListener
  21. {
  22.  
  23.     // Incoming data from client.
  24.     public static string data = null;
  25.  
  26.     // Thread signal.
  27.     public static ManualResetEvent allDone = new
ManualResetEvent(false);
  28.  
  29.     public AsynchronousSocketListener()
  30.     {
  31.     }
  32.  
  33.     public static void StartListening()
  34.     {
  35.         // Data buffer for incoming data.
  36.         byte[] bytes = new Byte[1024];
  37.  
  38.         // Establish the local endpoint for the socket.
  39.         // The DNS name of the computer
  40.         // running the listener is "host.contoso.com".
  41.         IPAddress ipAddress =
Dns.GetHostEntry("192.168.1.33").AddressList[2];
  42.         IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 4070);
  43.  
  44.         // Create a TCP/IP socket.
  45.         Socket listener = new Socket(AddressFamily.InterNetwork,
  46.             SocketType.Stream, ProtocolType.Tcp);
  47.  
  48.         // Bind the socket to the local endpoint and listen for
incoming connections.
  49.         try
  50.         {
  51.             listener.Bind(localEndPoint);
  52.             listener.Listen(100);
  53.  
  54.             while (true)
  55.             {
  56.                 // Set the event to nonsignaled state.
  57.                 allDone.Reset();
  58.  
  59.                 // Start an asynchronous socket to listen for
connections.
  60.                 Console.WriteLine("Waiting for a connection...");
  61.                 listener.BeginAccept(
  62.                     new AsyncCallback(AcceptCallback),
  63.                     listener);
  64.  
  65.                 // Wait until a connection is made before
continuing.
  66.                 allDone.WaitOne();
  67.             }
  68.  
  69.         }
  70.         catch (Exception e)
  71.         {
  72.             Console.WriteLine(e.ToString());
  73.         }
  74.  
  75.         Console.WriteLine("\nPress ENTER to continue...");
  76.         Console.Read();
  77.  
  78.     }
  79.  
  80.     public static void AcceptCallback(IAsyncResult ar)
  81.     {
  82.         // Signal the main thread to continue.
  83.         allDone.Set();
  84.  
  85.         // Get the socket that handles the client request.
  86.         Socket listener = (Socket)ar.AsyncState;
  87.         Socket handler = listener.EndAccept(ar);
  88.  
  89.         // Create the state object.
  90.         StateObject state = new StateObject();
  91.         state.workSocket = handler;
  92.         handler.BeginReceive(state.buffer, , StateObject.BufferSize,
,
  93.             new AsyncCallback(ReadCallback), state);
  94.     }
  95.  
  96.     public static void ReadCallback(IAsyncResult ar)
  97.     {
  98.         String content = String.Empty;
  99.  
 100.         // Retrieve the state object and the handler socket
 101.         // from the asynchronous state object.
 102.         StateObject state = (StateObject)ar.AsyncState;
 103.         Socket handler = state.workSocket;
 104.  
 105.         // Read data from the client socket.
 106.         int bytesRead = handler.EndReceive(ar);
 107.  
 108.         if (bytesRead > )
 109.         {
 110.             // There  might be more data, so store the data received
so far.
 111.             state.sb.Append(Encoding.ASCII.GetString(
 112.                 state.buffer, , bytesRead));
 113.  
 114.             // Check for end-of-file tag. If it is not there, read
 115.             // more data.
 116.             content = state.sb.ToString();
 117.             if (content.IndexOf("\n") > -1)
 118.             {
 119.                 // All the data has been read from the
 120.                 // client. Display it on the console.
 121.                 Console.WriteLine("Read {0} bytes from socket. \n
Data : {1}",
 122.                     content.Length, content);
 123.                 // Echo the data back to the client.
 124.                 Send(handler, content);
 125.             }
 126.             else
 127.             {
 128.                 // Not all data received. Get more.
 129.                 handler.BeginReceive(state.buffer, ,
StateObject.BufferSize, ,
 130.                 new AsyncCallback(ReadCallback), state);
 131.             }
 132.         }
 133.     }
 134.  
 135.     private static void Send(Socket handler, String data)
 136.     {
 137.         // Convert the string data to byte data using ASCII
encoding.
 138.         byte[] byteData = Encoding.ASCII.GetBytes(data);
 139.  
 140.         // Begin sending the data to the remote device.
 141.         handler.BeginSend(byteData, , byteData.Length, ,
 142.             new AsyncCallback(SendCallback), handler);
 143.     }
 144.  
 145.     private static void SendCallback(IAsyncResult ar)
 146.     {
 147.         try
 148.         {
 149.             // Retrieve the socket from the state object.
 150.             Socket handler = (Socket)ar.AsyncState;
 151.  
 152.             // Complete sending the data to the remote device.
 153.             int bytesSent = handler.EndSend(ar);
 154.             Console.WriteLine("Sent {0} bytes to client.",
bytesSent);
 155.  
 156.             handler.Shutdown(SocketShutdown.Both);
 157.             handler.Close();
 158.  
 159.         }
 160.         catch (Exception e)
 161.         {
 162.             Console.WriteLine(e.ToString());
 163.         }
 164.     }
 165.  
 166.  
 167.     public static int Main(String[] args)
 168.     {
 169.         StartListening();
 170.         return ;
 171.     }
 172. }
 173.  
 

However, the way it is, the client connects to this server and send a
message. The server reads it, and then disconnect the client. I need that
the client is still connected, and can continue to send many messages as it
wants.
On one hand I know that I have to remove the following lines of
SendCallBack method, so that the client is still connected:
<pre lang="midl">handler.Shutdown (SocketShutdown.Both)
handler.Close ();
Anyway, How can I do to enable the client to continue sending messages? Do
I must add a loop? Where?
 
Thanks!
Posted 20-Sep-10 18:32pm
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

See the lines marked with "new" - You're pretty close to a working piece of code already.
124.                 Send(handler, content); 
new.                 // All data received. Get next message. 
new.                 handler.BeginReceive(state.buffer,StateObject.BufferSize, 
new.                       new AsyncCallback(ReadCallback), state);
125.             } 
126.             else 
127.             { 
128.                 // Not all data received. Get more. 
129.                 handler.BeginReceive(state.buffer,StateObject.BufferSize, 
130.                       new AsyncCallback(ReadCallback), state);
 
And as you concluded - don't close the connection in the Send method, wait until the client sends a "close" message.
 
Regards
Espen Harlinn
  Permalink  
v2
Comments
SAKryukov at 10-Feb-11 17:07pm
   
Nice modification, my 5. This is the problem following a code sample before trying to create one's own code: the sample might be for different task.
--SA
Espen Harlinn at 10-Feb-11 17:38pm
   
Thanks SAKryukov!
JF2015 at 14-Feb-11 5:05am
   
Good answer. 5+
Espen Harlinn at 14-Feb-11 14:15pm
   
Thank you JF2015!
saeedazam786 at 20-Dec-12 1:19am
   
Hi,nice modification.can you please tell me how can i use if condition in it.for example if client send "hello" then server response is "hi" and if client send "how are you" then server send "i am fine".
Thanks in advance
Member 10885956 at 15-Jun-14 17:13pm
   
Hi All,
 
The solution was brilliant. However, I'm having a problem with the second message (while the client is still connected). It it's shorter than the first, the remaining/excess characters are being appended by the first.
 
Ex.
 
First message : 1111122222
Second message (actual) : 33333
Second message (what the program reads) : 1111133333
 
How do I clear the contents of the stateobject without messing up the whole thing?
 
Help. Pardon me as I am quite new to this.
 
Thank you.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

No dont use a loop. Creating a polling sort of a maechanism using a timer.
  Permalink  
Comments
juanporto at 29-Sep-10 17:33pm
   
Reason for my vote of 5
Automatic vote of 5 for accepting answer.
juanporto at 29-Sep-10 17:39pm
   
Thank you for your answer, but could you give an example of this polling mechanism? Thank you in advance.

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 520
1 Mathew Soji 315
2 Shweta N Mishra 269
3 BillWoodruff 240
4 OriginalGriff 235
0 OriginalGriff 6,168
1 Sergey Alexandrovich Kryukov 5,818
2 DamithSL 4,988
3 Manas Bhardwaj 4,539
4 Maciej Los 3,775


Advertise | Privacy | Mobile
Web04 | 2.8.1411019.1 | Last Updated 10 Feb 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100