/// <summary> /// Read responses from socket /// </summary> /// <param name="ct"></param> /// <returns></returns> public async Task <BrowseResponse> BrowseNextAsync(CancellationToken ct) { if (!_connected) { throw new SocketException(SocketError.Closed); } Message message; while (!ReceiveQueue.TryDequeue(out message)) { await ReceiveAsync(ct).ConfigureAwait(false); } ProxySocket.ThrowIfFailed(message); if (message.Error != (int)SocketError.Success) { throw new SocketException((SocketError)message.Error); } if (message.TypeId != MessageContent.Data) { throw new SocketException("No data message"); } var data = message.Content as DataMessage; if (data == null) { throw new SocketException("Bad data"); } var stream = new MemoryStream(data.Payload); var response = await BrowseResponse.DecodeAsync(stream, _codec, ct); response.Interface = message.Proxy.ToSocketAddress(); return(response); }
/// <summary> /// The implementation of the mechanism running in thread. /// </summary> void Receive() { while (true) { if (Running) { MessageEx incomingMessage; while (!ReceiveQueue.TryDequeue(out incomingMessage)) { Thread.Sleep(50); } UserDefined_ReceiveMessageProcedure(incomingMessage); } else { Thread.Sleep(50); } } }
/// <summary> /// The internal thread procedure, handling recv and send. /// </summary> protected void ThreadProc() { // cleanup old socket if any if (socket != null) { socket.Close(); socket = null; } // reset the packetcontroller messageController.Reset(); // clean pending messages/exceptions from queues GameMessage message; Exception error; while (SendQueue.TryDequeue(out message)) { ; } while (ReceiveQueue.TryDequeue(out message)) { ; } while (ExceptionQueue.TryDequeue(out error)) { ; } // init a new Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // try connect to server try { socket.Connect(serverAddress, serverPort); } catch (Exception Error) { ExceptionQueue.Enqueue(Error); } // don't go on if no connection if (socket.Connected) { // initialize the socket stream tcpStream = new NetworkStream(socket); // mark running isRunning = true; // start thread loop // this can be broken by calling Disconnect() while (isRunning) { try { bool doSend = false; // processing pending messages to send while (SendQueue.TryDequeue(out message)) { Send(message, false); doSend = true; } // call flush ourself here // so we can send multiple messages above if (doSend) { Flush(); } // read if (socket.Available > 0) { messageController.ReadRecv(tcpStream, socket.Available); } // avoid 100% cpu usage Thread.Sleep(SLEEPTIME); } catch (Exception Error) { // log the exception ExceptionQueue.Enqueue(Error); // stop thread isRunning = false; } } } // cleanup if (socket != null) { socket.Close(); } // reset references socket = null; tcpStream = null; workThread = null; }