本文介绍了C# - 多线程服务器 - 客户端流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我已经实现了发送消息客户端 - >服务器并实际连接多个客户端。但我想要做的是连接2个客户端并让他们自己聊天。如果第三个客户连接 - 那么他就开始和其他客户聊天。 到现在为止,我正处于聊天客户端> server->客户端的舞台上与另一个c-> s-> c分开。会发生什么 - 我运行client1,一切正常。然后我运行client2并且使用它一切正常,但第一个客户端停止工作,然后我在第二个客户端上获得的第一条消息是我从client1发送的最后一条消息(但实际上并没有收到它服务器)。 所以我认为流有问题 - 两个客户以某种方式获得彼此的流。 这是一些部分服务器(相关的): class TheServer { private TcpListener tcpListener; private Thread threadListener; TheMessage消息; public TcpClient [] clientList = new TcpClient [ 100 ]; private int n = 0 ; public void StartServer() { 尝试 { 此 .tcpListener = new TcpListener(IPAddress.Any, 8000 ); 此 .threadListener = 新主题( new ThreadStart(ListenForClients)); this .threadListener.Start(); Console.WriteLine( 本地终点: + tcpListener.LocalEndpoint ); } catch (例外e) { throw ; } } 私有 void ListenForClients( ) { this .tcpListener.Start(); while ( true ) { // 阻止,直到客户端连接到服务器 TcpClient client = 此 .tcpListener.AcceptTcpClient(); if (n == 0 ) { clientList [ 0 ] =客户; } else { n ++; clientList [n] =客户端; } // 创建线程来处理与连接客户端的通信 线程clientThread = new 线程( new ParameterizedThreadStart(HandleClientComm)); clientThread.Start(clientList [n]); } } private void HandleClientComm( object client) { TcpClient tcpClient =(TcpClient)client; NetworkStream stm = clientList [n] .GetStream(); msg = new TheMessage(); while ( true ) { 字节 [] bSize = new 字节 [ sizeof ( Int32 )]; stm.Read(bSize, 0 ,bSize.Length); 字节 [] bData = new 字节 [BitConverter.ToInt32(bSize, 0 )]; stm.Read(bData, 0 ,bData.Length); msg = XmlRefactorServer.ByteArrayToObject< TheMessage>(bData); String str = msg.Message; Console.WriteLine(str); stm.Flush(); // 发送回客户 msg.Message =海峡; Byte [] bDataBack = XmlRefactorServer.ObjectToByteArray< TheMessage>(msg); stm = clientList [n] .GetStream(); 字节 [] bSizeBack = BitConverter.GetBytes(bDataBack.Length); stm.Write(bSizeBack, 0 ,bSizeBack.Length); stm.Write(bDataBack, 0 ,bDataBack.Length); stm.Flush(); } tcpClient.Close(); } HandleClientComm(对象客户端)正在处理接收发送操作。 这里是客户端代码部分,它处理接收 - 发送操作: while ( true ) { msg.Message = Console.ReadLine( ); Byte [] bData = XmlRefacrotClient.ObjectToByteArray< TheMessage>(msg); Stream stm = client.GetStream(); 字节 [] bSize = BitConverter.GetBytes(bData.Length); stm.Write(bSize, 0 ,bSize.Length); stm.Write(bData, 0 ,bData.Length); stm.Flush(); Console.WriteLine( 发送到服务器!); // 从服务器读回来 Console.WriteLine( 从服务器收到!); 字节 [] bSizeBack = new 字节 [ sizeof ( Int32 )]; stm.Read(bSizeBack, 0 ,bSizeBack.Length); 字节 [] bDataBack = new 字节 [BitConverter.ToInt32(bSizeBack, 0 )]; stm.Read(bDataBack, 0 ,bDataBack.Length); msg = XmlRefacrotClient.ByteArrayToObject< TheMessage>(bDataBack); String str = msg.Message; Console.WriteLine(str); stm.Flush(); } 我得到类型' System.OutOfMemoryException' 字节 [] bData = new 字节 [BitConverter.ToInt32(bSize, 0 )]; sooo ..是的,溪流有问题(我认为)。 我对任何建议持开放态度。解决方案 问题出在HandleClientComm()的开头并且确切地说: private void HandleClientComm(对象客户端) { TcpClient tcpClient =(TcpClient)客户端; NetworkStream stm = clientList [n] .GetStream(); msg = new TheMessage(); 所以我必须得到''tcpClient''的流,而不是''clientList [n]''的流。 I have achieved sending message client -> server and actually connecting many clients simultaneously. But what I want to do is i.e. connect 2 clients and make them chat between themselves. And if 3rd client connects - then so he starts chatting with both other clients.By now I am on the stage of chatting client->server->client separately from another c->s->c. What happens is - I run client1 and everything is OK. Then I run client2 and with it everything is OK, but the 1st client stops working and then the first message I acquire on the 2nd client is the last message that I sent from client1 (but that didn''t actually receive back to it from server).So I suppose there''s problem with the streams - that the 2 clients somehow acquire each-other''s streams.Here is the some parts of the server (relevant ones):class TheServer { private TcpListener tcpListener; private Thread threadListener; TheMessage msg; public TcpClient[] clientList = new TcpClient[100]; private int n = 0; public void StartServer() { try { this.tcpListener = new TcpListener(IPAddress.Any, 8000); this.threadListener = new Thread(new ThreadStart(ListenForClients)); this.threadListener.Start(); Console.WriteLine("Local end point: " + tcpListener.LocalEndpoint); } catch (Exception e) { throw; } } private void ListenForClients() { this.tcpListener.Start(); while(true) { // block until a client has connected to the server TcpClient client = this.tcpListener.AcceptTcpClient(); if (n == 0) { clientList[0] = client; } else { n++; clientList[n] = client; } // create thread to handle communication with connected client Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm)); clientThread.Start(clientList[n]); } } private void HandleClientComm(object client) { TcpClient tcpClient = (TcpClient)client; NetworkStream stm = clientList[n].GetStream(); msg = new TheMessage(); while (true) { Byte[] bSize = new Byte[sizeof(Int32)]; stm.Read(bSize, 0, bSize.Length); Byte[] bData = new Byte[BitConverter.ToInt32(bSize, 0)]; stm.Read(bData, 0, bData.Length); msg = XmlRefactorServer.ByteArrayToObject<TheMessage>(bData); String str = msg.Message; Console.WriteLine(str); stm.Flush(); // send back to client msg.Message = str; Byte[] bDataBack = XmlRefactorServer.ObjectToByteArray<TheMessage>(msg); stm = clientList[n].GetStream(); Byte[] bSizeBack = BitConverter.GetBytes(bDataBack.Length); stm.Write(bSizeBack, 0, bSizeBack.Length); stm.Write(bDataBack, 0, bDataBack.Length); stm.Flush(); } tcpClient.Close(); }HandleClientComm(object client) is handling the receive-send operations.And here is the client side code part, that handles the receive-send operations:while (true){ msg.Message = Console.ReadLine(); Byte[] bData = XmlRefacrotClient.ObjectToByteArray<TheMessage>(msg); Stream stm = client.GetStream(); Byte[] bSize = BitConverter.GetBytes(bData.Length); stm.Write(bSize, 0, bSize.Length); stm.Write(bData, 0, bData.Length); stm.Flush(); Console.WriteLine("Sent to server!"); // reading back from server Console.WriteLine("Received from server!"); Byte[] bSizeBack = new Byte[sizeof(Int32)]; stm.Read(bSizeBack, 0, bSizeBack.Length); Byte[] bDataBack = new Byte[BitConverter.ToInt32(bSizeBack, 0)]; stm.Read(bDataBack, 0, bDataBack.Length); msg = XmlRefacrotClient.ByteArrayToObject<TheMessage>(bDataBack); String str = msg.Message; Console.WriteLine(str); stm.Flush(); }And I get An unhandled exception of type 'System.OutOfMemoryException' occurred in in the Server at Byte[] bData = new Byte[BitConverter.ToInt32(bSize, 0)]; sooo... yeah, there''s something wrong with the streams (on my opinion).I am open for any suggestions. 解决方案 The problem was in the beginning of HandleClientComm() and precisely:private void HandleClientComm(object client){ TcpClient tcpClient = (TcpClient)client; NetworkStream stm = clientList[n].GetStream(); msg = new TheMessage();So I had to get the stream for ''tcpClient'', not not for ''clientList[n]''. 这篇关于C# - 多线程服务器 - 客户端流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!