using SharedClientServer; using System; using System.Collections.Generic; using System.Net.Sockets; using System.Text; namespace Server.Models { class ServerClient : ObservableObject { public string Username { get; set; } private TcpClient tcpClient; private NetworkStream stream; private byte[] buffer = new byte[1024]; private byte[] totalBuffer = new byte[1024]; private int totalBufferReceived = 0; public ServerClient(TcpClient client) { tcpClient = client; stream = tcpClient.GetStream(); stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnRead), null); } /// /// callback method that gets called when the stream has finished reading a message from the stream. /// /// the async result status private void OnRead(IAsyncResult ar) { int bytesReceived = this.stream.EndRead(ar); if (totalBufferReceived + bytesReceived > 1024) { throw new OutOfMemoryException("buffer is too small!"); } // copy the received bytes into the buffer Array.Copy(buffer, 0, totalBuffer, totalBufferReceived, bytesReceived); // add the bytes we received to the total amount totalBufferReceived += bytesReceived; // calculate the expected length of the message int expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); while (totalBufferReceived >= expectedMessageLength) { // we have received the full packet byte[] message = new byte[expectedMessageLength]; // copy the total buffer contents into the message array so we can pass it to the handleIncomingMessage method Array.Copy(totalBuffer, 0, message, 0, expectedMessageLength); HandleIncomingMessage(message); // move the contents of the totalbuffer to the start of the array Array.Copy(totalBuffer, expectedMessageLength, totalBuffer, 0, (totalBufferReceived - expectedMessageLength)); totalBufferReceived -= expectedMessageLength; expectedMessageLength = BitConverter.ToInt32(totalBuffer, 0); if (expectedMessageLength == 0) { break; } } // start reading for a new message stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(OnRead), null); } /// /// Method to handle incoming message data /// /// the incoming message private void HandleIncomingMessage(byte[] message) { //TODO implement ways to handle the message } /// /// sends a message to the tcp client /// /// message to send public void sendMessage(byte[] message) { stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null); } /// /// callback method that gets called when the stream has finished writing the message /// /// the async result status private void OnWrite(IAsyncResult ar) { stream.EndWrite(ar); } } }