/// <summary> /// Called when new data arrives. Checks to see how much data has arrived: /// /// If 0: connection has been closed (presumably by the server) /// If > 0: get SocketState out of stateAsArObject and call the callMe provided /// </summary> /// <param name="stateAsArObject"> /// SyncResult containing the SocketState where callMe is saved away. /// </param> public static void ReceiveCallback(IAsyncResult stateAsArObject) { SocketState ss = (SocketState)stateAsArObject.AsyncState; try { if (ss.Connected) { int bytesRead = ss.TheSocket.EndReceive(stateAsArObject); // If the socket is still open if (bytesRead > 0) { string theMessage = Encoding.UTF8.GetString(ss.MessageBuffer, 0, bytesRead); // Append the received data to the growable buffer. // It may be an incomplete message, so we need to start building it up piece by piece ss.SB.Append(theMessage); } ss.CallMe(ss); } } catch (Exception e) { System.Diagnostics.Debug.WriteLine(e.Message); ss.Connected = false; } }
/// <summary> /// BeginAcceptSocket's callback function. When connection comes in, this method: /// (1) extracts the state containing the TcpListener and the callMe function from ar. /// (2) creates a new socket by using lister.EndAcceptSocket /// (3) save socket in new SocketState /// (4) call the callMe method and pass it to the new SocketState. This is how the server /// gets a copy of the SocketState corresponding to this client. The callMe should /// save the SocketState in a list of clients. /// (5) Await a new connection request (coninued in the event loop) with BeginAcceptSocket. /// This means that the networking code assumes we want to always continue the event loop. /// </summary> /// <param name="ar">contains the callMe and the TcpListener</param> public static void AcceptNewClient(IAsyncResult ar) { ConnectionState cs = (ConnectionState)ar.AsyncState; SocketState ss = new SocketState(cs.Lstn.EndAcceptSocket(ar), ++IDCounter); ss.CallMe = cs.CallMe; ss.CallMe(ss); cs.Lstn.BeginAcceptSocket(AcceptNewClient, cs); }
/// <summary> /// Reference by BeginConnect above and is called when socket connects to /// server. Once connection established, saved callMe is then called /// (originally passed in the ConnectToServer in SocketState) /// </summary> /// <param name="stateAsArObject"> /// Contains a field "AsyncState" which contains SocketState saved away for /// later use. /// </param> public static void ConnectedCallback(IAsyncResult stateAsArObject) { SocketState ss = (SocketState)stateAsArObject.AsyncState; try { // Complete the connection. ss.TheSocket.EndConnect(stateAsArObject); System.Diagnostics.Debug.WriteLine("connected to server"); } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Unable to connect to server. Error occured: " + e); return; } ss.CallMe(ss); }