/// <summary> /// /// This function is referenced by the BeginConnect method above and /// is "called" by the OS when the socket connects to the server. The ///"ar" object contains a field "AsyncState" which ///contains the "state" object saved away in the above function. ///Once a connection is established the "saved away" callbackFunction ///needs to be called. This function is saved in the socket state, and was ///originally passed in to ConnectToServer. /// </summary> /// <param name="ar"></param> public static void ConnectedToServer(IAsyncResult ar) { SocketState ss = (SocketState)ar.AsyncState; try { // Complete the connection. ss.theSocket.EndConnect(ar); ss.Connected = true; } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Unable to connect to server. Error occured: " + e); //Set connected to false because the socket did not connect to a server. ss.Connected = false; } // TODO: If we had a "EventProcessor" delagate stored in the state, we could call that, // instead of hard-coding a method to call. ss.CallMe(ss); //Check if the socketState is connected. if (ss.Connected == true) { ss.theSocket.BeginReceive(ss.messageBuffer, 0, ss.messageBuffer.Length, SocketFlags.None, ReceiveCallback, ss); } }
/// <summary> /// Method to be called when data has been received /// </summary> /// <param name="ar"></param> private static void ReceiveCallback(IAsyncResult ar) { SocketState ss = (SocketState)ar.AsyncState; int bytesRead = 0; try { //A client may be disconnected bytesRead = ss.theSocket.EndReceive(ar); } catch (SocketException se) { ss.DisconnectCallback(ss); } // 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); } }
/// <summary> /// Accepts a new client onto the server. Uses the action delegate from the /// connectionState and Begins the Accept Socket again for more clients. /// </summary> /// <param name="ar"></param> public static void AcceptNewClient(IAsyncResult ar) { Console.WriteLine("A client has started connection to the Server"); Console.Read(); ConnectionState cs = (ConnectionState)ar.AsyncState; Socket socket = cs.Listener.EndAcceptSocket(ar); SocketState ss = new SocketState(); ss.theSocket = socket; ss.CallMe = cs.CallMe; ss.CallMe(ss); cs.Listener.BeginAcceptSocket(AcceptNewClient, cs); }
/// <summary> /// This Callback goes off once data has been sent /// </summary> /// <param name="ar"></param> private static void SendCallback(IAsyncResult ar) { // pull out the socket state SocketState ss = (SocketState)ar.AsyncState; // End the send ss.theSocket.EndSend(ar); // Check if sendcallback is null if (ss.SendCallback != null) { // Do whatever the socketstate wants to do after finishing sending ss.CallMe(ss); } }
/// <summary> /// The ReceiveCallback method is called by the OS when new data arrives. This method should check to see how much data has arrived. If 0, the ///connection has been closed(presumably by the server). On greater than zero data, this method should call the callback function provided above. /// </summary> /// <param name="state_in_an_ar_object"></param> public static void ReceiveCallback(IAsyncResult ar) { SocketState ss = (SocketState)ar.AsyncState; //Check if the socket is connected if (!ss.theSocket.Connected) { return; } int bytesRead = 0; try { bytesRead = ss.theSocket.EndReceive(ar); } catch (Exception) { //MessageBox.Show("The server disconnected."); //The socket is no longer connected to the server. ss.Connected = false; } // 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); } else { ss.Connected = false; EndConnection(ss); return; } // Continue the "event loop" that was started on line 154. // Start listening for more parts of a message, or more new messages ss.CallMe(ss); }
/// <summary> /// This function is "called" by the operating system when the remote site acknowledges connect request /// </summary> /// <param name="ar"></param> private static void ConnectedCallback(IAsyncResult ar) { // Extract the SocketState SocketState ss = (SocketState)ar.AsyncState; try { // Complete the connection. ss.theSocket.EndConnect(ar); } catch (Exception e) { // Connection failed System.Diagnostics.Debug.WriteLine("Unable to connect to server. Error occured: " + e); return; } // Do whatever the socket state wants us to do when we finally connect ss.CallMe(ss); // Starting the event loop and receiving data ss.theSocket.BeginReceive(ss.messageBuffer, 0, ss.messageBuffer.Length, SocketFlags.None, Networking.ReceiveCallback, ss); }