TCP聊天:服务器发送给多个客户端
TCP Chat : Server sends to multiple client
所以我正在使用 TCP 协议进行 C# 聊天,我无法弄清楚如何让服务器将客户端接收到的数据发送到连接到他的所有客户端。所以我试图将所有客户端放入一个数组列表中,并使用 "foreach" 向它们发送服务器接收到的数据 like in this topic 但我失败了。
为了发送和接收数据,我正在使用 Streams (StreamWriter / StreamReader)。每个客户端都由服务器在不同的线程中处理。
问题:如何同时向所有客户端发送数据?
服务器:
static void LoopClients()
{
while (running)
{
TcpClient newClient = server.AcceptTcpClient();
arrClient.add(newClient)
Console.WriteLine("Connection accepted from " + ((IPEndPoint)newClient.Client.RemoteEndPoint).Address);
Thread t = new Thread(new ParameterizedThreadStart(HandleClient));
t.Start(newClient);
}
}
static void HandleClient(object obj)
{
TcpClient client = (TcpClient)obj;
StreamWriter Writer = new StreamWriter(client.GetStream(), Encoding.ASCII);
StreamReader Reader = new StreamReader(client.GetStream(), Encoding.ASCII);
Boolean ClientConnected = true;
String Data = null;
var LEP = client.Client.RemoteEndPoint as IPEndPoint;
var LAD = LEP.Address;
while (ClientConnected)
{
Data = Reader.ReadLine();
Console.WriteLine(""+ LAD + " : " + Data);
Writer.WriteLine(LAD+" : "+Data+"");
Writer.Flush();
}
}
谢谢!
本质上,您需要以某种方式跟踪所有客户。这 可以 就像跟踪同步集合中的所有 StreamWriter
一样简单,并确保在会话终止时从中删除。例如:
StreamWriter Writer = new StreamWriter(client.GetStream(), Encoding.ASCII);
try {
lock(allClients) { allClients.Add(Writer); }
while (ClientConnected)
{
...
}
} finally {
lock(allClients) { allClients.Remove(Writer); }
}
现在,当我们想向所有人发送消息时,我们需要做一些事情。也许最简单的事情是同步扫描:
lock(allClients) {
foreach(var writer in allClients)
try { writer.Send(message); } catch { /* log */ }
}
这会同步整个集合 - 所以只要这是 唯一 发送消息的地方,那么你就会知道:你永远不会尝试发送到同一个地方socket 一次两次,并且 b: 你不会通过使用 socket add/remove.
来破坏迭代器
警告:这是 multi-client 服务器的非常非常粗糙和基本的实现,实际上只应用作该主题的 介绍 。 "Real" multi-client 服务器应该 多 比这更偏执。
所以我正在使用 TCP 协议进行 C# 聊天,我无法弄清楚如何让服务器将客户端接收到的数据发送到连接到他的所有客户端。所以我试图将所有客户端放入一个数组列表中,并使用 "foreach" 向它们发送服务器接收到的数据 like in this topic 但我失败了。 为了发送和接收数据,我正在使用 Streams (StreamWriter / StreamReader)。每个客户端都由服务器在不同的线程中处理。
问题:如何同时向所有客户端发送数据?
服务器:
static void LoopClients()
{
while (running)
{
TcpClient newClient = server.AcceptTcpClient();
arrClient.add(newClient)
Console.WriteLine("Connection accepted from " + ((IPEndPoint)newClient.Client.RemoteEndPoint).Address);
Thread t = new Thread(new ParameterizedThreadStart(HandleClient));
t.Start(newClient);
}
}
static void HandleClient(object obj)
{
TcpClient client = (TcpClient)obj;
StreamWriter Writer = new StreamWriter(client.GetStream(), Encoding.ASCII);
StreamReader Reader = new StreamReader(client.GetStream(), Encoding.ASCII);
Boolean ClientConnected = true;
String Data = null;
var LEP = client.Client.RemoteEndPoint as IPEndPoint;
var LAD = LEP.Address;
while (ClientConnected)
{
Data = Reader.ReadLine();
Console.WriteLine(""+ LAD + " : " + Data);
Writer.WriteLine(LAD+" : "+Data+"");
Writer.Flush();
}
}
谢谢!
本质上,您需要以某种方式跟踪所有客户。这 可以 就像跟踪同步集合中的所有 StreamWriter
一样简单,并确保在会话终止时从中删除。例如:
StreamWriter Writer = new StreamWriter(client.GetStream(), Encoding.ASCII);
try {
lock(allClients) { allClients.Add(Writer); }
while (ClientConnected)
{
...
}
} finally {
lock(allClients) { allClients.Remove(Writer); }
}
现在,当我们想向所有人发送消息时,我们需要做一些事情。也许最简单的事情是同步扫描:
lock(allClients) {
foreach(var writer in allClients)
try { writer.Send(message); } catch { /* log */ }
}
这会同步整个集合 - 所以只要这是 唯一 发送消息的地方,那么你就会知道:你永远不会尝试发送到同一个地方socket 一次两次,并且 b: 你不会通过使用 socket add/remove.
来破坏迭代器警告:这是 multi-client 服务器的非常非常粗糙和基本的实现,实际上只应用作该主题的 介绍 。 "Real" multi-client 服务器应该 多 比这更偏执。