private void LogSocketObject(BaseSocketObject socketObject, string message) { if (socketObject.Action != SocketConstants.SocketAction.Ping || ConfigValues.LogPings) { Logger.LogDebug(message); } }
/// <summary> Threaded callback that will churn through the Write Queue and send the items out. </summary> private void WriteStart() { while (!this.IsStopping) { try { // Safely dequeue an item, if any exists BaseSocketObject socketObject = null; lock (this.writeQueue) { if (this.writeQueue.Any()) { socketObject = this.writeQueue.Dequeue(); } } // If an item was dequeued, send it. // Otherwise, wait until one is enqueue. // If one was enqueue after we checked if one was available to dequeue, then the event will already be Set so the WaitOne will return immediately. if (socketObject != null) { Write(socketObject); } else { this.writeQueueEvent.WaitOne(); } } catch { } } }
/// <summary> Adds the Socket Object to the Write Queue and notifies the Write thread. </summary> private void EnqueueWrite(BaseSocketObject socketObject) { lock (this.writeQueue) { this.writeQueue.Enqueue(socketObject); this.writeQueueEvent.Set(); } }
private BaseSocketObject WaitAndRead() { var allBytes = new List <byte[]>(); try { // Get the first Int32 to find out how many bytes we should expect. var bytesExpectedBuffer = new byte[4]; server.Receive(bytesExpectedBuffer); var bytesExpected = BitConverter.ToInt32(bytesExpectedBuffer, 0); Logger.LogDebug(string.Format("Expecting {0} more bytes (4 read already, so {1} total read for this message).", bytesExpected, bytesExpected + 4)); var bytesBuffer = new byte[bytesExpected]; // Loop until we get all the bytes we're expecting. We should get it in one shot, but it'll depend on how the packet sizes in use. var bytesReceived = 0; while (bytesReceived < bytesExpected) { // Read either a full buffer's worth, or just up to how many we're expecting. This prevents data that is enqueued // behind this object from being read in and corrupting the data. var bytesToRead = Math.Min(bytesExpected - bytesReceived, bytesBuffer.Length); var thisBytesReceived = server.Receive(bytesBuffer, bytesToRead, SocketFlags.None); if (thisBytesReceived > bytesToRead) { throw new InvalidOperationException(string.Format("Socket has been corrupted in some way, as a maximum of {0} bytes were requested but {1} bytes were read.", bytesToRead, thisBytesReceived)); } bytesReceived += thisBytesReceived; allBytes.Add(bytesBuffer.Take(thisBytesReceived).ToArray()); } //while (true) //{ // var bytesReceived = new byte[1024]; // var bytesReceivedCount = server.Receive(bytesReceived); // var actualBytesReceived = (bytesReceivedCount == bytesReceived.Length) ? bytesReceived.ToArray() : bytesReceived.Take(bytesReceivedCount).ToArray(); // // If we never received our End Of Data flag, then we must keep going. // allBytes.Add(actualBytesReceived); // if (actualBytesReceived.Last() == (byte)SocketConstants.SocketAction.EndOfData) // break; //} var allBytesConcat = allBytes.SelectMany(b => b).ToArray(); Logger.LogDebug(string.Format("Read {0} of expected {1} total bytes.", allBytesConcat.Length, bytesExpected)); return(BaseSocketObject.BaseObjectFromBytes(allBytesConcat)); } catch (Exception e) { var readBytesCount = allBytes.SelectMany(b => b).Count(); Logger.LogError(string.Format("Client Socket - An error occurred reading data from the server. Read {0} bytes before failure.", readBytesCount), e); return(null); } }
/// <summary> Writes the Socket Object to the clients, if any are connected. Consumes all exceptions. </summary> private void Write(BaseSocketObject socketObject) { if (ClientsCount == 0) { return; } try { LogSocketObject(socketObject, string.Format("Server Socket - Writing Socket Object '{0}'.", socketObject)); var bytes = socketObject.GetBytes(); var sendBytes = BitConverter.GetBytes(bytes.Length).Concat(bytes).ToArray(); LogSocketObject(socketObject, string.Format("Server Socket - Writing {0} total bytes.", sendBytes.Length)); lock (clients) { for (var c = 0; c < clients.Count; c++) { var client = clients[c]; try { LogSocketObject(socketObject, string.Format("Server Socket - Writing to '{0}'.", client.Address)); client.Send(sendBytes); if (OnSocketEvent != null) { switch (socketObject.Action) { // Pings never raise up the event, otherwise we'd be flooded with events. case SocketConstants.SocketAction.Ping: break; default: OnSocketEvent(new ServerEvent(client, socketObject.Action)); break; } } } catch (Exception e) { if (e is SocketException && ((SocketException)e).SocketErrorCode != SocketError.ConnectionAborted) { Logger.LogError(string.Format("Server Socket - Client socket '{0}' has been closed already. Fully disconnecting client now.", client.Address), e); } else { Logger.LogError(string.Format("Server Socket - Failed to write Socket Object '{0}' to Client '{1}'. Disconnecting client.", socketObject, client.Address), e); } // Remove the element from the list and repeat the index, since the subsequent items would shift down. SafeCloseClient(client); clients.RemoveAt(c); if (client is ClientNetSocket) { NetClientsCount--; } else if (client is ClientWebSocket) { WebClientsCount--; } if (OnClientCountChanged != null) { OnClientCountChanged(ClientsCount); } c--; } } } LogSocketObject(socketObject, string.Format("Server Socket - Done writing Socket Object '{0}'.", socketObject)); } catch (Exception e) { Logger.LogError(string.Format("Server Socket - Failed to write Socket Object '{0}'.", socketObject), e); } }