private static void ContinueReceiveCallback(IAsyncResult ar) { // Store the response state from the receive callback to continue receiving. ResponeState state = (ResponeState)ar.AsyncState; // Amount of bytes received int received; try { // Receive the data and store the amount of bytes received = state.Socket.EndReceive(ar); // Store the response as a string after conversion from bytes to string string response = Encoding.UTF8.GetString(Buffer); // Add the string to the response state response string builder state.Response.Append(Encoding.UTF8.GetString(Buffer).Substring(0, received)); // Reduce the amount of bytes remaining by the amount received state.RemainingBytes -= received; // If there is still data left then continue receiving with the ContinueReceiveCallback if (state.RemainingBytes > 0) { state.Socket.BeginReceive(Buffer, 0, BufferSize, SocketFlags.None, ContinueReceiveCallback, state); } else { // Else recieve for a new request state.Socket.BeginReceive(Buffer, 0, BufferSize, SocketFlags.None, ReceiveCallback, state.Socket); // Handle the request. RequestHandler.Handle(state.Response.ToString(), state.Socket); } // Information Console.WriteLine($"$ Request from {state.Socket.RemoteEndPoint}: {state.Response}"); } catch (SocketException) { // If a socket exception is encountered then close the socket, shut it down and remove it. CloseErrorSocket(state.Socket); return; } catch (Exception) { // If any exception is encountered then close the socket, shut it down and remove it. CloseErrorSocket(state.Socket); return; } }
private static void ReceiveCallback(IAsyncResult ar) { // End receiving if server is closing if (Closing) { return; } // Create a ResponseState to pass into the async calls to retrieve all data if it is longer than the buffer ResponeState state = new ResponeState(); state.Socket = (Socket)ar.AsyncState; // The amount of data received int received; try { // Receive the data and store the amount received = state.Socket.EndReceive(ar); // Get the current response string response = Encoding.UTF8.GetString(Buffer); // The length of data is the first thing received, it is parsed and stored in the ResponseState string length = response.Split(' ')[0]; state.RemainingBytes = int.Parse(length); // Append the data received so far state.Response.Append(Encoding.UTF8.GetString(Buffer).Substring(length.Length + 1, received - length.Length - 1)); // Reduce the received data from the remaining state.RemainingBytes -= received; // Information Console.WriteLine($"$ Request from {state.Socket.RemoteEndPoint}: {state.Response}"); // If there is still data left receive more and call the callback to handle more data if (state.RemainingBytes > 0) { state.Socket.BeginReceive(Buffer, 0, BufferSize, SocketFlags.None, ContinueReceiveCallback, state); } else { // If the data received is EXT, then close the socket and shut it down and close the receiving loop if (state.Response.ToString() == "EXT") { state.Socket.Shutdown(SocketShutdown.Both); state.Socket.Close(); ConnectedSockets.Remove(state.Socket); return; } // Continue receiving state.Socket.BeginReceive(Buffer, 0, BufferSize, SocketFlags.None, ReceiveCallback, state.Socket); // Handle the request sent from the client RequestHandler.Handle(state.Response.ToString(), state.Socket); } } catch (SocketException) { // If a socket exception is encountered then close the socket, shut it down and remove it. CloseErrorSocket(state.Socket); return; } catch (Exception) { // If any exception is encountered then close the socket, shut it down and remove it. CloseErrorSocket(state.Socket); return; } }