//----------------------------------------------------------- // Async handlers //----------------------------------------------------------- private void OnClientConnect(IAsyncResult async) { _log4.Debug("SocketServer OnClientConnect"); if (_mainSocket == null) { return; } ServerReplyContext serverReplyContext = null; try { // Here we complete/end the BeginAccept() asynchronous call // by calling EndAccept() - which returns the reference to // a new Socket object var workerSocket = _mainSocket.EndAccept(async); // Now increment the client count for this client // in a thread safe manner Interlocked.Increment(ref _clientCount); // Add the workerSocket reference to the list _socketList.GetOrAdd(_clientCount, workerSocket); serverReplyContext = new ServerReplyContext(this, workerSocket, _clientCount); _log4.Debug("Opened Socket #" + _clientCount); SetStatus(ServiceStatus.Connected); SendNotification(ServiceNotification.ClientConnected, CurrentStatus, serverReplyContext); // Send a welcome message to client // TODO: Notify client # & IP address //string msg = "Welcome client " + _clientCount + "\n"; //SendMsgToClient(msg, m_clientCount); // Let the worker Socket do the further processing for the // just connected client BeginReceive(serverReplyContext); } catch (SocketException se) { SendNotification(ServiceNotification.Error, CurrentStatus, serverReplyContext, String.Format("OnClientConnect: {0}, {1:X} ({2})", se.Message, se.HResult, se.SocketErrorCode)); // See http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx //if (se.SocketErrorCode == SocketError.ConnectionReset) // WSAECONNRESET (10054) { // Forcibly closed CloseSocket(serverReplyContext); } } catch (Exception e) { SendNotification(ServiceNotification.Error, CurrentStatus, serverReplyContext, String.Format("OnClientConnect: {0}", e.Message)); CloseSocket(serverReplyContext); } // Since the main Socket is now free, it can go back and wait for // other clients who are attempting to connect SetStatus(ServiceStatus.Waiting); _mainSocket.BeginAccept(OnClientConnect, null); }
// Start waiting for data from the client private void BeginReceive(ServerReplyContext serverReplyContext) { _log4.Debug("SocketServer BeginReceive"); try { serverReplyContext.Socket.BeginReceive(serverReplyContext.DataBuffer, 0, serverReplyContext.DataBuffer.Length, SocketFlags.None, OnDataReceived, serverReplyContext); } catch (SocketException se) { SendNotification(ServiceNotification.Error, CurrentStatus, serverReplyContext, String.Format("BeginReceive: {0}, {1:X} ({2})", se.Message, se.HResult, se.SocketErrorCode)); CloseSocket(serverReplyContext); } }
// Start waiting for data from the client private void BeginReceive(ServerReplyContext serverReplyContext) { Log4.Debug("SocketServer BeginReceive"); try { _ = serverReplyContext.Socket.BeginReceive(serverReplyContext.DataBuffer, 0, serverReplyContext.DataBuffer.Length, SocketFlags.None, OnDataReceived, serverReplyContext); } catch (SocketException se) { SendNotification(ServiceNotification.Error, CurrentStatus, serverReplyContext, $"BeginReceive: {se.Message}, {se.HResult:X} ({se.SocketErrorCode})"); CloseSocket(serverReplyContext); } }
private void CloseSocket(ServerReplyContext serverReplyContext) { Log4.Debug("SocketServer CloseSocket"); if (serverReplyContext == null) { return; } // Remove the reference to the worker socket of the closed client // so that this object will get garbage collected _ = _clientList.TryRemove(serverReplyContext.ClientNumber, out var socket); if (socket != null) { Log4.Debug("Closing Socket #" + serverReplyContext.ClientNumber); Interlocked.Decrement(ref _clientCount); SendNotification(ServiceNotification.ClientDisconnected, CurrentStatus, serverReplyContext); socket.Close(); } }
public override void Send(string text, Reply replyContext = null) { base.Send(text, replyContext); if (text is null) { throw new ArgumentNullException(nameof(text)); } if (CurrentStatus != ServiceStatus.Connected || _mainSocket == null) { return; } if (replyContext == null) { foreach (var i in _clientList.Keys) { if (_clientList.TryGetValue(i, out var client)) { Reply reply = new ServerReplyContext(this, client, i); Send(text, reply); } } } else { if (((ServerReplyContext)replyContext).Socket.Send(Encoding.UTF8.GetBytes(text)) > 0) { SendNotification(ServiceNotification.Write, CurrentStatus, replyContext, text.Trim()); } else { SendNotification(ServiceNotification.WriteFailed, CurrentStatus, replyContext, text); } } }