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;
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);
}
}
{
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 }
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 }
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 }
以上是服务端的大致模型 将在以后持续修改