2017-08-17 61 views
-1

我正在使用我的方式槽套接字教程,并且遇到问题。我有3班;服务器,ServerClient和客户端。 Server监听连接请求,ServerClient是服务器端Socket封装器,Client是试图连接的用户端程序。将套接字传递给客户端后断开/关闭

我面临的问题是,当服务器将接受的套接字传递给ServerClient类时,套接字断开连接。如果我调试Socket通过了已连接= 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。

+0

如果没有好的[mcve],它将无法帮助您解决代码中的所有问题。但是至于你的断开问题,它正在发生**,因为你正在断开套接字**。你在'ServerClient'构造函数中做的最后一件事是调用一些'Disconnect()'方法。毫无疑问,这种方法可以断开或关闭套接字。因此你的问题。 –

+0

不,不是这样,因为在等待ListenToClient()之后才会调用Disconnect。那还没有完成。除了atm,Disconnect()是空的。 –

+0

_“在等待ListenToClient()之后才会调用Disconnect();”_ - **是,就是这样。**只要ListenToClient()返回一个不完整的任务,您的Run()方法就会返回。在一段延长的时间内有一个构造块会是一个可怕的设计(所以即使你是对的,你的代码也会被破坏),但是对于await的工作方式你完全错了。 'Run()'方法在'await'完成时返回_before_,允许构造函数完成执行,包括调用'Disconnect()'。 –

回答

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); 
    } 
相关问题