2012-11-22 27 views
3

我设计使用异步等待的方法,利用事件驱动的.NET环境中,具有以下特点的异步TCP服务器:简单的异步等待TCP服务器的设计

  1. 请求和响应功能。
  2. 服务器端发起的事件。

这种服务器设计在异步等待方法方面是否正确?
下面的代码仅涵盖了判断我是否缺少某些东西的基本功能。
服务器使用COM类型库,这是PRMasterAutomation类的来源。

public class AsyncServer { 
    private const int BufferSize = 4096; 
    private static bool ServerRunning = true;  
    private List<TcpClient> clients = new List<TcpClient>(); 
    private PRMasterAutomation automation; 

    public AsyncServer() 
    {    
     InitializeComponent(); 
     automation = new PRMasterAutomation(); 
     automation.OnMonitoringEvent += automation_OnMonitoringEvent; 

     if (!automation.Login("ADMIN", "")) 
      return;    

     if (automation.GetPRMasterState() == PRMasterStateEnum.StateIdle) 
      automation.StartMonitoring(); 

     var tcpServer = new TcpListener(IPAddress.Any, 9001); 
     tcpServer.Start(); 
     ListenForClients(tcpServer);      
    } 

    private async void ListenForClients(TcpListener tcpServer) 
    { 
     while (ServerRunning) 
     { 
      TcpClient tcpClient = await tcpServer.AcceptTcpClientAsync(); 
      clients.Add(tcpClient); 
      ProcessClient(tcpClient); 
     } 
    } 

    private async void ProcessClient(TcpClient tcpClient) 
    { 
     var stream = tcpClient.GetStream(); 
     var buffer = new byte[BufferSize]; 
     int amountRead; 
     string xml; 
     while (ServerRunning)    
     { 
      if ((amountRead = await stream.ReadAsync(buffer, 0, BufferSize)) > 0) 
      { 
       var message = Encoding.ASCII.GetString(buffer, 0, amountRead); 
       xml = ""; 
       if (message.Equals("get_users")) 
       { 
        xml = automation.GetUsersXml();            
       } 
       else if (message.Equals("get_events")) 
       { 
        xml = automation.GetEventsHistoryXml(""); 
       } 

       if (xml.Length > 0) 
       { 
        xml += "\r\n"; 
        await stream.WriteAsync(Encoding.ASCII.GetBytes(xml), 0, xml.Length); 
       } 
      } 
     } 
    } 

    async void automation_OnMonitoringEvent(DateTime date, DateTime time, int networkID, int readerID, int userID, int groupID, int eventCode, int zoneID, int TandAID, string strEvent, string strAccessPoint, string strUserSource, string strGroup, string strNetwork, string strZone, string strTandAMode) 
    { 
     foreach (var c in clients) 
     { 
      if (c != null && c.Connected) 
      { 
       var stream = c.GetStream(); 
       StringBuilder sb = new StringBuilder(); 
       sb.Append(date.ToString() + ";" + time.ToString() + ";" + networkID.ToString() + ";" + userID.ToString() + "\r\n"); 
       await stream.WriteAsync(Encoding.ASCII.GetBytes(sb.ToString()), 0, sb.Length); 
      } 
     }    
    } 
} 
+1

实际上它接受下一个客户端,因为调用'amountRead = await stream.ReadAsync(buffer,0,BufferSize)'不会阻塞并允许继续接受客户端。 – koszyczeq

回答

4

请问这服务器的设计是异步等待的方法而言是否正确?

是的,但不是套接字。 ReadAsync将返回1和无限之间的任何数量的字节,它不会返回消息。

Stream.ReadAsync():结果值可以小于所请求的字节的数量,如果当前可用的字节数少于所请求的数量,或者它可以是0(零),如果流的末尾一直到达。

您必须创建一个缓冲区并继续读取并添加到该缓冲区,直到您知道收到完整的消息。这意味着在你的情况下检查\r\n。如果遇到这样的分隔符,可以从缓冲区中提取消息并开始接收新消息。

+0

谢谢你的回复。你是完全正确的,插座部分处理不好,它还没有完成。异步等待服务器设计的审批是我关注的。 – koszyczeq