C# 处理连接到套接字服务器的每个套接字客户端

C# 处理连接到套接字服务器的每个套接字客户端,c#,.net,sockets,C#,.net,Sockets,我最近刚刚开始使用Socket开发一个服务器多客户端应用程序 服务器不需要跟踪连接的客户端;若有一个客户端请求连接,服务器就会接受它。若有来自任何客户机的请求(获取一些数据),服务器将响应该客户机 /// <summary> /// Callback when server accepts a new incoming connection. /// </summary> /// <param name="result">Incoming connection

我最近刚刚开始使用Socket开发一个服务器多客户端应用程序

服务器不需要跟踪连接的客户端;若有一个客户端请求连接,服务器就会接受它。若有来自任何客户机的请求(获取一些数据),服务器将响应该客户机

/// <summary>
/// Callback when server accepts a new incoming connection.
/// </summary>
/// <param name="result">Incoming connection result object.</param>
private void AcceptedCallback(IAsyncResult result)
{
  try
  {
      Socket clientSocket = _socket.EndAccept(result); // Asynchronously accepts an incoming connection attempt

      if (clientSocket.Connected)  // Check if the client is in 'Connected' state
      {
        StateObject state = new StateObject();
        state.clientSocket = clientSocket;
        clientSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, // Start listening to client request
                                  ReceiveCallback, state);
      }
      else
      {
            clientSocket.Close();    // Terminate that client's connection
        Log.writeLog("TCPServer(AcceptedCallback)"
                     , "Client's status is not connected.");
      }
  }
  catch (Exception ex)
  {
      Log.writeLog("TCPServer(AcceptedCallback)"
                 , ex.Message);
      clientSocket.Close();
  }
  finally
  {
      Accept(); // Start to accept new connection request
  }
}
//
///当服务器接受新的传入连接时回调。
/// 
///传入连接结果对象。
私有void AcceptedCallback(IAsyncResult结果)
{
尝试
{
Socket clientSocket=\u Socket.EndAccept(result);//异步接受传入的连接尝试
if(clientSocket.Connected)//检查客户端是否处于“已连接”状态
{
StateObject状态=新的StateObject();
state.clientSocket=clientSocket;
clientSocket.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,//开始侦听客户端请求
ReceiveCallback,state);
}
其他的
{
clientSocket.Close();//终止该客户端的连接
Log.writeLog(“TCPServer(AcceptedCallback)”
,“客户端的状态未连接。”);
}
}
捕获(例外情况除外)
{
Log.writeLog(“TCPServer(AcceptedCallback)”
,例如讯息);
clientSocket.Close();
}
最后
{
Accept();//开始接受新的连接请求
}
}
关于这一点,我有三个问题:

  • 对于我为新连接的客户端创建的每个BeginReceive,我的服务器应用程序是否创建一个新线程/对象来容纳该客户端

  • 如果在连接客户端之后,在客户端拔下网络电缆并重新插入,客户端将再次连接到服务器,这被视为服务器上的新连接,如果这种情况一再发生,我的服务器程序会崩溃吗

  • 因此,我是否需要跟踪连接到服务器的每个客户机,并找到跟踪其状态的方法,以便对其调用Close/Dispose

  • 到目前为止,在我对场景2的测试中,在我的服务器程序中没有检测到异常,但我希望有人能帮我澄清这一点。多谢各位

  • 否,它将使用线程池中的IO完成线程
  • 不,您可以编写代码,也应该编写代码以满足此需求。如果在客户端发生操作系统可以检测到的事情,它将向服务器发送TCP fin/ack。这将导致任何BeginXXX方法仍在等待异步回调方法。从那里,对EndXXX方法的调用应该抛出异常或返回从套接字读取的零字节
  • 这取决于您所说的跟踪以正确处置它们的意思。如果您的意思是在检测到错误时处理它们,则可以在EndXXX方法中放置清理代码。如果您的意思是,如果关闭服务器,您可以优雅地向客户端发出信号,那么是的

  • 谢谢你的迅速回复。根据你的答复,我可以得出如下结论:1。不会为每个连接的客户端创建额外的内存/资源。2.我有一个清理代码来处理这种情况,比如“从那里,您对EndXXX方法的调用应该抛出一个异常,或者返回从套接字读取的零字节。”但不需要在导致此错误的客户端(在服务器程序)上调用Dispose/Close。如果我错了,请纠正我。您不必创建线程,它将由操作系统处理。2.您可能不必调用close或dispose,如果这样做,您可能会得到ObjectAlreadyDisposed异常。但你可以这样做,而且大多数人无论如何都会这样做,以确保100%的安全。他们只是抓住了ObjeTaleRead Debug,因为在这种情况下,几乎是意料之中的。我明白了,谢谢,我认为这个案子现在已经结束了。