2013-06-30 207 views
0

我有一个TCP IP服务器应用程序接受多个客户端并处理他们的请求。管理连接的TCP客户端

其中之一,我需要处理被发送到客户端的反应迟缓,更具体的情况,这里是我的设计细节和协议:

A)客户端发送一个请求做的工作,并且服务器成功接收并启动该作业。

B)服务器,时间长了以后,需要搜索该客户端连接,并告诉他,他的工作完成

我的方法是如下:

  • 在客户端的连接,我生成一个Class的新实例,该实例持有刚刚连接的客户端实例和唯一的令牌,以便我可以跟踪客户端请求并异步回复他,让我们称这个类为MyConnectedClient

  • 然后,我插入这个MyConnectedClient实例到客户的Hashtable,独特的令牌是他的钥匙,和值是MyConnectedClient


  • 实例现在,当作业已完成,具体取决于传递给作业的客户端令牌,我可以从已连接的客户端列表中检索客户端并将备忘录发送给客户端。此外,当客户端连接死亡时,我引发事件并将令牌与其一起发送,因此,我的服务器将从连接的客户端列表中删除MyConnectedClient实例。


基本上,这是我的用户管理设计,正如我所说,这是工作的罚款和足够我的需要,但问题是,有没有更好的方式来处理连接的客户端?

去除死皮的客户或者找一个客户端,较早提出的要求?

完成下面的代码示例:

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 
using System.Collections; 

namespace TCPIPIPC.Server 
{ 
    public class Server 
    { 
     int publicToken = 0; 

     public class ConnectedClient 
     { 
      public TcpClient tcpClient; 
      public DateTime connectedSince; 
      public int token; 
     } 

     Hashtable ClientList; 

     #region Variable declaration 
     /// <summary> 
     /// Main TCP listener 
     /// </summary> 
     private TcpListener tcpListener; 

     /// <summary> 
     /// Main server thread 
     /// </summary> 
     private Thread listenThread; 

     /// <summary> 
     /// Event handler for received message from the server 
     /// </summary> 
     /// <param name="message"></param> 
     public delegate void ServerMessageEventHandler(string message, ConnectedClient client); 

     /// <summary> 
     /// Event handler for connected client to the server 
     /// </summary> 
     /// <param name="tcpClient"></param> 
     public delegate void clientconnectedEventHandler(ConnectedClient client); 

     /// <summary> 
     /// Event to be raised when data received from the server 
     /// </summary> 
     public event ServerMessageEventHandler MessageReceived; 

     /// <summary> 
     /// Event to be raised when a client is Connected/Disconnected to the server 
     /// </summary> 
     public event clientconnectedEventHandler ClientConnected; 
     public event clientconnectedEventHandler ClientDisconnected; 

     public IList Items; 
     #endregion 

     /// <summary> 
     /// Constructor, Server initialization 
     /// </summary> 
     public Server(IPAddress listenerAddress, int listenerPort) 
     { 
      ClientList = new Hashtable(); 
      ClientDisconnected += new clientconnectedEventHandler(Server_ClientDisconnected); 
      this.tcpListener = new TcpListener(listenerAddress, listenerPort); //new TcpListener(IPAddress.Any, 3000); 
      this.listenThread = new Thread(new ThreadStart(ListenForClients)); 
      this.listenThread.Start(); 
     } 

     /// <summary> 
     /// Remove disconnected clients 
     /// </summary> 
     /// <param name="client"></param> 
     void Server_ClientDisconnected(Server.ConnectedClient client) 
     { 
      if (ClientList.ContainsKey(client.token)) 
      { 
       ClientList.Remove(client.token); 
      } 
     } 

     /// <summary> 
     /// Main listener thread start 
     /// </summary> 
     private void ListenForClients() 
     { 
      this.tcpListener.Start(); 
      while (true) 
      { 
       //blocks until a client has connected to the server 
       TcpClient client = this.tcpListener.AcceptTcpClient(); 

       var connecteItem = new ConnectedClient(); 

       connecteItem.tcpClient = client; 
       connecteItem.connectedSince = DateTime.Now; 
       connecteItem.token = publicToken++; 

       //create a thread to handle communication 
       //with connected client 
       Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm)); 
       clientThread.Start(client); 

       //Raise client connected event 
       if (ClientConnected != null) 
       { 
        ClientConnected(connecteItem); 
       } 
      } 
     } 

     /// <summary> 
     /// Client communication handler 
     /// </summary> 
     /// <param name="client">the received connection from the client of type TcpClient</param> 
     private void HandleClientComm(object client) 
     { 
      ConnectedClient currentClient = (ConnectedClient)client; 
      TcpClient tcpClient = currentClient.tcpClient; 
      NetworkStream clientStream = tcpClient.GetStream(); 

      byte[] message = new byte[4096]; 
      int bytesRead; 

      while (true) 
      { 
       bytesRead = 0; 

       try 
       { 
        //blocks until a client sends a message 
        bytesRead = clientStream.Read(message, 0, 4096); 
       } 
       catch 
       { 
        //a socket error has occurred 
        break; 
       } 

       if (bytesRead == 0) 
       { 
        //the client has disconnected from the server 
        break; 
       } 

       //message has successfully been received 
       ASCIIEncoding encoder = new ASCIIEncoding(); 

       //Raise message received event 
       if (MessageReceived != null) 
       { 
        MessageReceived(encoder.GetString(message, 0, bytesRead), currentClient);//This will be caught by a parent worker who will start a job based on this request 
       } 

       //System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead)); 
      } 

      tcpClient.Close(); 

      if (ClientDisconnected != null) 
      { 
       ClientDisconnected(currentClient); 
      } 
     } 

     /// <summary> 
     /// This method sends a message to a connected client 
     /// </summary> 
     /// <param name="tcpClient">The connected TcpClient client instance to send a message to</param> 
     /// <param name="message">The message to send to the client</param> 
     public void SendMessage(TcpClient tcpClient, string message) 
     { 
      NetworkStream clientStream = tcpClient.GetStream(); 
      ASCIIEncoding encoder = new ASCIIEncoding(); 
      byte[] buffer = encoder.GetBytes(message); 

      clientStream.Write(buffer, 0, buffer.Length); 
      clientStream.Flush(); 
     } 
    } 
} 

请不高于该代码没有完全定型,但它说明了想法

回答

1

只是作业的客户端套接字相关联,并有工作任务写入对该套接字的响应。如果失败,客户端已断开连接。你并不需要所有其他爵士乐。

+0

好点,谢谢 – simsim