private void SendMessage() { IMessage message; var q = _messageOutQueue; if (q == null || !q.TryTake(out message, -1)) { return; } byte[] buffer; try { // Custom serialization buffer = CustomFormatter.Serialize(message); } catch (Exception e) { Log.Error("Invalid message to serialize, closing connection.", e); Stop(); return; } lock (lockObject) { if (TcpSocket == null || !TcpSocket.Connected) { Log.Error("Tried to send message " + message + " while not connected."); return; } try { TcpSocket.BeginSend( buffer, 0, buffer.Length, 0, new AsyncCallback(SendTcpCallback), this); } catch (SocketException se) { Log.Error("Error sending, closing connection", se); Stop(); return; } } }
private static void ReceiveTcpCallback(IAsyncResult ar) { // Retrieve the state object and the client socket // from the async state object. var client = (Connection)ar.AsyncState; lock (client.lockObject) { if (client.TcpSocket == null) { return; } int bytesRead; try { // Read data from the remote device. bytesRead = client.TcpSocket.EndReceive(ar); } catch (ArgumentException) { // this is the result of a previous connection, we discard it return; } catch (SocketException e) { client.Log.Error("Error reading, closing connection.", e); client.Stop(); return; } if (bytesRead == 0) { client.Log.Info("Connection closed by remote."); client.Stop(); return; } client._tcpOffset += bytesRead; while (client._tcpOffset > MessageTypeMap.MessageLengthLength) { int expectedLength = BitConverter.ToInt16(client._tcpbuffer, 0); if (client._tcpOffset >= expectedLength) { IMessage message; try { message = (IMessage)CustomFormatter.Deserialize(client._tcpbuffer); } catch (Exception e) { client.Log.Error("Invalid packet received, closing connection.", e); client.Stop(); return; } if (client._messageInQueue.TryAdd(message)) { client.Log.Trace("enqueued " + message.GetType() + " message"); if (client.MessageRecieved != null) { client.MessageRecieved(client, new MessageEventArgs(message)); } } else { client.Log.Error("Failed to enqueue " + message.GetType() + " message"); } // copy the remaining data to the front of the buffer client._tcpOffset -= expectedLength; if (client._tcpOffset > 0) { Array.Copy(client._tcpbuffer, expectedLength, client._tcpbuffer, 0, client._tcpOffset); } } } // listen for the next message client.BeginReading(); } }