예제 #1
0
        //-----------------------------------------------------------
        // 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);
        }
예제 #2
0
 // 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);
     }
 }
예제 #3
0
 // 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);
     }
 }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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);
                }
            }
        }