/// <summary> /// This function is referenced by the BeginConnect method above and is "called" by the OS when the socket connects to the server. The "state_in_an_ar_object" object contains a field "AsyncState" which contains the "state" object saved away in the above function. /// Once a connection is established the "saved away" callback function needs to called. Additionally, the network connection should "BeginReceive" expecting more data to arrive(and provide the ReceiveCallback function for this purpose) /// </summary> /// <param name="state_in_an_ar_object"></param> static void Connected_to_Server(IAsyncResult ar) { Preserved_State state = (Preserved_State)ar.AsyncState; //Call the first callback, which resets some info in the state state.GUI_Callback(ar); state.buffer = new byte[BUFFER_SIZE]; if (state.socket.Connected) { state.socket.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), state); } }
/// <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. /// For our purposes, this function should not request more data.It is up to the code in the callback function above to request more data. /// </summary> /// <param name="state_in_an_ar_object"></param> static void ReceiveCallback(IAsyncResult ar) { Preserved_State state = (Preserved_State)ar.AsyncState; Socket socket = state.socket; byte[] buffer = (byte[])state.buffer; //If the connection was forcibly closed on the server's end, handle that if (socket.Connected == false) { CloseGracefully(socket); return; } //Try to stop receiving this current request int byte_count = 0; try { byte_count = socket.EndReceive(ar); } catch (Exception e) { //If we couldn't stop the reception, close gracefully CloseGracefully(socket); } if (byte_count == 0) { //Connection lost CloseGracefully(socket); return; } else { string the_string = encoding.GetString(buffer, 0, byte_count); state.sb.Append(the_string); //If the last character is a newline, we're done receiving, so we can call the callback in the GUI if (the_string.LastIsNewline()) { state.GUI_Callback(ar); } //If the last character isn't a newline, we know we're not done receiving yet, so we need to ask for more data (after appending to the string builder else { i_want_more_data(ar); } } }