将套接字传递给客户端类后断开/关闭套接字

时间:2017-08-17 14:28:58

标签: c# sockets server client disconnected

我正在通过套接字教程工作,我正在遇到问题。我有3个班级;服务器,ServerClient和客户端。服务器侦听连接请求,ServerClient是服务器端套接字包装器,客户端是尝试连接的用户端程序。

我面临的问题是,当服务器将接受的套接字传递给ServerClient类时,Socket会断开连接。如果我调试Socket传递了Connected = True,但是当我在ServerClient中设置局部变量时,它变为Connected = False。

在客户端,我没有遇到问题,但我知道Socket仍然处于连接状态。

我做错了什么,还有什么比我的代码更糟糕?

服务器:

    public async void Run()
    {
        //
        if (AcceptingClients)
        {
            // Error already running
            return;
        }

        //
        LoadSettings();

        //
        IPEndPoint localEndPoint = new IPEndPoint(_settings.Ip, _settings.Port);

        // Start The Server
        _server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _server.Bind(localEndPoint);
        _server.Listen(100);

        // 
        AcceptingClients = true;

        //
        OnServerStart(EventArgs.Empty);

        // Running => Accept connections
        await AcceptConnections();

        // Stopped => Close connections
        await CloseConnections();

        // Server Stopped => Finish stuff

        //
        OnServerStop(EventArgs.Empty);
    }
    private async Task AcceptConnections()
    {
        await Task.Run(() =>
        {
            while (AcceptingClients)
            {
                try
                {
                    // Set the _acceptConnectionDone to nonsignaled state.  
                    _acceptConnectionDone.Reset();

                    //
                    _server.BeginAccept(AcceptConnectionsCallback, _server);

                    // Wait until a connection is made before continuing.  
                    _acceptConnectionDone.WaitOne();
                }
                catch
                {
                    //
                }
            }
        });
    }
    private static void AcceptConnectionsCallback(IAsyncResult ar)
    {
        // Signal the AcceptConnections Task to continue.  
        _acceptConnectionDone.Set();

        // 
        if (!AcceptingClients)
        {
            // Server Stopping or stopped
            return;
        }

        // Get the socket that handles the client request.  
        Socket server = (Socket)ar.AsyncState;
        Socket client = server.EndAccept(ar);

        // Create the client object.  
        ServerClient newclient = new ServerClient(client);

        // Add Events


        //
        _connections.TryAdd(_totalConnectionCount++, newclient);
    }

ServerClient:

    private readonly Socket _connection;

    //
    public ServerClient(Socket s)
    {
        //
        _connection = s;

        //
        Run();

        // Disconnected or needs to be disconnected => Process
        Disconnect();
        return;
    }
    private async void Run()
    {
        //
        if (_connection.Connected)
        {
            //
            _connection.ReceiveBufferSize = ServerExt.ReadBufferSize;
            _connection.SendBufferSize = ServerExt.SendBufferSize;
            _connection.NoDelay = true;

            //
            await ListenToClient();
        }
    }

客户端:

    public async void Connect()
    {
        if (_connection != null)
        {
            // Check if we are not connected already

        }

        //
        LoadSettings();

        //
        try
        {
            //
            IPEndPoint remoteEndPoint = new IPEndPoint(_settings.Ip, _settings.Port);

            // Create a TCP/IP socket.  
            _connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            {
                ReceiveBufferSize = ServerExt.ReadBufferSize,
                SendBufferSize = ServerExt.SendBufferSize,
                NoDelay = true
            };

            // Connect to the remote endpoint.  
            _connection.Connect(remoteEndPoint);

            //
            if (_connection.Connected)
            {
                //
                await ListenToServer();
            }
        }
        catch
        {
            //

        }

        // Disconnected or needs to be disconnected => Process
        Disconnect();
        return;
    }

日Thnx。

1 个答案:

答案 0 :(得分:0)

我设法通过更改ServerClient的代码来保持连接打开。

    public ServerClient(int id, Socket s, ClientConnectedDelegate connected, ClientDisconnectedDelegate disconnected)
    {
        //
        Id = id;

        //
        _connection = s;
        _disconnected = disconnected;

        //
        Ip = _connection.RemoteIp();

        //
        _connection.ReceiveBufferSize = ServerExt.ReadBufferSize;
        _connection.SendBufferSize = ServerExt.SendBufferSize;
        _connection.NoDelay = true;

        //
        _netStream = new NetworkStream(_connection, FileAccess.ReadWrite);

        //
        if (_cert != null)
        {
            _ssl = new SslStream(_netStream, false);
            _ssl.AuthenticateAsServer(_cert, false, SslProtocols.Tls, true);

            // 
            _br = new BinaryReader(_ssl, Encoding.UTF8, false);
            _bw = new BinaryWriter(_ssl, Encoding.UTF8, false);
        }
        else
        {
            _br = new BinaryReader(_netStream, Encoding.UTF8, false);
            _bw = new BinaryWriter(_netStream, Encoding.UTF8, false);
        }

        //
        Task.Factory.StartNew(ListenToClient);

        //
        connected(this);
    }