I am currently developing a Socket Socket server that can accept multiple connections from multiple client computers. The purpose of the server is to allow clients to "subscribe" and "unsubscribe" from server events.
So far I have looked good here: http://msdn.microsoft.com/en-us/library/5w7b7x5f(v=VS.100).aspx and http://msdn.microsoft.com/en-us/library /fx6588te.aspx for ideas.
All sent messages are encrypted, so I take the string message that I want to send, convert it to a byte [] array, and then encrypt the data before bringing the message length to the data and sending it over the connection.
One thing that strikes me as a problem is this: on the receiving side, it seems possible that Socket.EndReceive () (or the associated callback) can return when only half of the message is received. Is there an easy way to ensure that each message is received βcompleteβ and only one message at a time?
EDIT: For example, I believe that .NET / Windows sockets do not "wrap" messages to ensure that one message sent from Socket.Send () is received in a single Socket.Receive () call? Or that?
My implementation so far:
private void StartListening() { IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); IPEndPoint localEP = new IPEndPoint(ipHostInfo.AddressList[0], Constants.PortNumber); Socket listener = new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); listener.Bind(localEP); listener.Listen(10); while (true) { // Reset the event. this.listenAllDone.Reset(); // Begin waiting for a connection listener.BeginAccept(new AsyncCallback(this.AcceptCallback), listener); // Wait for the event. this.listenAllDone.WaitOne(); } } private void AcceptCallback(IAsyncResult ar) { // Get the socket that handles the client request. Socket listener = (Socket) ar.AsyncState; Socket handler = listener.EndAccept(ar); // Signal the main thread to continue. this.listenAllDone.Set(); // Accept the incoming connection and save a reference to the new Socket in the client data. CClient client = new CClient(); client.Socket = handler; lock (this.clientList) { this.clientList.Add(client); } while (true) { this.readAllDone.Reset(); // Begin waiting on data from the client. handler.BeginReceive(client.DataBuffer, 0, client.DataBuffer.Length, 0, new AsyncCallback(this.ReadCallback), client); this.readAllDone.WaitOne(); } } private void ReadCallback(IAsyncResult asyn) { CClient theClient = (CClient)asyn.AsyncState; // End the receive and get the number of bytes read. int iRx = theClient.Socket.EndReceive(asyn); if (iRx != 0) { // Data was read from the socket. // So save the data byte[] recievedMsg = new byte[iRx]; Array.Copy(theClient.DataBuffer, recievedMsg, iRx); this.readAllDone.Set(); // Decode the message recieved and act accordingly. theClient.DecodeAndProcessMessage(recievedMsg); // Go back to waiting for data. this.WaitForData(theClient); } }
Siyfion
source share