C#【Fox即时通讯核心】 开发记录之四(服务端多线程异步处理数据 主程序大致结构)

目前这个是服务端主程序大致的结构

以后可能进一步修改 使用连接池

 

代码
1  private   bool  running  =   false ;
2  private  IPAddress serverIP;
3  private  TcpListener listener;
4  private  Thread WaitTread;  // 监听客户线程 响应多个客户端的连接请求 等待客户端登陆
5  private  TcpClient remoteClient; // 远程连接
6  public   static  Hashtable userTable;

 

初步确定的服务端主程序字段 在以后的更改中可能考虑使用数据集代替哈希表维持一个在线客户列表

 

private   void  WaitingClient()
{
    
while  (running)
    {
        remoteClient 
=  listener.AcceptTcpClient(); // 同步方法
        RemoteClient newclient  =   new  RemoteClient(remoteClient);
    }
    
}

 

 

监听线程专门处理这个任务 一直等待客户端的连接。当有连接时就实例化一个客户对象

 

客户对象在构造函数中就开始异步调用接收用户数据 接收完成后就调用处理数据的回调函数 回调函数处理完数据再开始异步调用,并在异步调用时传递自身作为回调函数

 

代码
 1  private  TcpClient client;
 2  private  NetworkStream streamToClient;
 3  private   const   int  bufferSize  =   8192 ;
 4  private   byte [] buffer;
 5  private   string  userName;
 6 
 7  public  RemoteClient(TcpClient client)
 8  {
 9       this .client  =  client;
10      streamToClient  =  client.GetStream();
11      buffer  =   new   byte [bufferSize];
12 
13       // 异步操作完成时调用的方法
14      AsyncCallback callBack  =   new  AsyncCallback(ReadComplete);
15      streamToClient.BeginRead(buffer,  0 , bufferSize, callBack,  null );  // 异步操作完成后将通知回调方法
16  }

 

 

构造远程客户对象的时候就开始异步读取客户请求

 

代码
 1  private   void  ReadComplete(IAsyncResult ar)  // 参数表示异步操作的状态
 2  {
 3       int  bytesRead  =   0 ;
 4      CustomMessage message;
 5       try
 6      {
 7           lock  (streamToClient)
 8          {
 9              bytesRead  =  streamToClient.EndRead(ar);
10          }
11           if  (bytesRead  ==   0 )
12               throw   new  Exception( " 读取到0字节 " );
13          message  =  (CustomMessage)SerializationHelper.Deserialize(buffer);
14           switch  (message.cmd)
15          {
16               case  Cmds.online:
17                  {
18                       // 把链接的用户加入到哈希表中
19                      Server.userTable.Add(message.message, client);
20                      userName = message.message;
21                      Server.richTextBox1.AppendText( " 已响应连接请求 "   +  client.Client.LocalEndPoint.ToString()  +   " <--- "   +  client.Client.RemoteEndPoint.ToString()  +   " \n " ); ;
22                      Server.richTextBox1.AppendText( " 用户  " + message.message + "  上线了\n " );
23 
24                      CustomMessage tempMessage  =   new  CustomMessage(userName, Cmds.online); // 上线信息
25                       // 通知其它用户
26                       foreach  ( object  c  in  Server.userTable.Values)
27                      {
28                          NetworkStream tempStream  =  ((TcpClient)c).GetStream(); 
29                           byte [] tempBuffer  =  SerializationHelper.Serialize(tempMessage); // 序列化
30                          tempStream.Write(tempBuffer,  0 , tempBuffer.Length);
31                      }
32                       break ;
33                  }
34               case  Cmds.messageToAll:
35                  {
36                      Server.richTextBox1.AppendText( " 接收到数据 "   +  message.message  +   " \n " );
37                       break ;
38                  }
39               default :
40                  {
41                       break ;
42                  }
43          }
44 
45 
46 
47          Array.Clear(buffer,  0 , buffer.Length); // 清空缓存
48 
49          streamToClient.Flush(); // 刷新流中数据 保留此方法供将来使用
50 
51           lock  (streamToClient)
52          {
53              AsyncCallback callBack  =   new  AsyncCallback(ReadComplete);
54              streamToClient.BeginRead(buffer,  0 , bufferSize, callBack,  null );
55          }
56      }
57       catch  (Exception ex)
58      {
59          Server.userTable.Remove(userName);
60          Server.richTextBox1.AppendText(userName  +   " 下线了!\n " );
61           // 从哈希表删除该用户
62          
63           if  (streamToClient  ==   null )
64              streamToClient.Dispose();
65          client.Close();
66      }
67  }

 

 

以上是服务端的大致模型 将在以后持续修改

你可能感兴趣的:(即时通讯)