/// <summary> /// This function is "called" by the operating system when the remote site acknowledges connect request /// </summary> /// <param name="ar"></param> public static void ConnectedToServer(IAsyncResult ar) { SocketState ss = (SocketState)ar.AsyncState; try { // Complete the connection. ss.theSocket.EndConnect(ar); //Send to the callback. ss.callBack(ss); //Gets data from the server as it arrives. AwaitDataFromServer(ss); } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Unable to connect to server. Error occured: " + e); IPAddress ipAddress = IPAddress.None; Socket tempsock = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); //I am not sure it is a good idea to send null back, but it is the only way I can think of checking for failed connect right now. //This indicates failure connecting. (ID:-1 and null socket for failure) SocketState d = new SocketState(tempsock, -1); //Send to the client our failed socketstate. (In the snake client case this should be first contact...) ss.callBack(d); return; } }
/// <summary> /// A function used when we receive a callback and can begin reading data sent /// </summary> /// <param name="ar"></param> public static void ReceiveCallback(IAsyncResult ar) { SocketState ss = (SocketState)ar.AsyncState; try { //Ends the reading operation so we can save it and process the data. int bytesRead = ss.theSocket.EndReceive(ar); // If the socket is still open if (bytesRead > 0) { //Save the data for processing. 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); //Send to the callback. ss.callBack(ss); } else { ss.theSocket.Disconnect(false); ss.shutdownSocket(); ss.callBack = null; return; } // Continue the "event loop" that was started on line 154. // Start listening for more parts of a message, or more new messages //ss.theSocket.BeginReceive(ss.messageBuffer, 0, ss.messageBuffer.Length, SocketFlags.None, ReceiveCallback, ss); } catch (Exception ex) { //Console.WriteLine("Receive + " + ex.Message); //IPAddress ipAddress = IPAddress.None; //Socket tempsock = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); //SocketState d = new SocketState(tempsock, -1); //Send to the client our failed socketstate. (In the snake client case this should be first contact...) //ss.callBack(d); ss.shutdownSocket(); } }
/// <summary> /// This starts an event loop to continuously listen for messages from the server. /// </summary> /// <param name="ss">The state representing the server connection</param> public static void AwaitDataFromServer(SocketState ss) { try { // Start listening for a message // When a message arrives, handle it on a new thread with ReceiveCallback ss.theSocket.BeginReceive(ss.messageBuffer, 0, ss.messageBuffer.Length, SocketFlags.None, new AsyncCallback(NetworkHandler.ReceiveCallback), ss); } catch (Exception ex) { Console.WriteLine("AwaitDataFromServer Exception"); SocketState d = new SocketState(null, -1); //Send to the client our failed socketstate. (In the snake client case this should be first contact...) ss.callBack(d); } }
private static void ConnectionRequested(IAsyncResult ar) { NewConnectionState cs = (NewConnectionState)ar.AsyncState; Socket socket = cs.Listener.EndAcceptSocket(ar); //Will have to change this ID to the client specific ID in server SocketState ss = new SocketState(socket, 0); ss.theSocket = socket; ss.callBack = cs.callBack; //??? isn't this redundant ss.callBack(ss); cs.Listener.BeginAcceptSocket(ConnectionRequested, cs); }