我尝试使用C#在控制台中创建服务器程序。我使用ThreadPool为每个客户端创建单独的套接字。然后,我创建一个static List<TcpClient> clients = new List<TcpClient>();
来包含连接到的所有客户端。
然后,我想要的是,当1个客户端向服务器发送消息时,服务器将接收并将其发送给所有连接的客户端。所以,我写道:
foreach (var item in clients)
{
ns.Write(data, 0, recv);
//send message to all client
}
但是,只有客户端发送的消息才能收回,另一个客户端什么都没收到!
****服务器端:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class ThreadedTcpSrvr
{
private TcpListener client;
//private
public ThreadedTcpSrvr()
{
client = new TcpListener(IPAddress.Parse("127.0.0.1"), 9050);
client.Start();
Console.WriteLine("Waiting for clients...");
while (true)
{
while (!client.Pending())
{
Thread.Sleep(1000);
}
ConnectionThread newconnection = new ConnectionThread();
newconnection.threadListener = this.client;
Thread newthread = new Thread(new
ThreadStart(newconnection.HandleConnection));
newthread.Start();
}
}
public static void Main()
{
ThreadedTcpSrvr server = new ThreadedTcpSrvr();
}
}
class ConnectionThread
{
static List<TcpClient> clients = new List<TcpClient>();
public TcpListener threadListener;
private static int connections = 0;
public void HandleConnection()
{
int recv;
byte[] data = new byte[1024];
TcpClient client = threadListener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
//TcpClient clientSocket = client.AccepTcpClient();
clients.Add(client);
connections++;
Console.WriteLine("New client accepted: {0} active connections",
connections);
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
ns.Write(data, 0, data.Length);
while (true)
{
data = new byte[1024];
recv = ns.Read(data, 0, data.Length);
if (recv == 0)
break;
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
//ns.Write(data, 0, recv);
foreach (var item in clients)
{
ns.Write(data, 0, recv);
//send message to client
}
}
ns.Close();
client.Close();
connections--;
Console.WriteLine("Client disconnected: {0} active connections",connections);
}
}
****客户方:
void ReceiveData(IAsyncResult iar)
{
try
{
while(true)
{
Socket remote = (Socket)iar.AsyncState;
int recv = remote.EndReceive(iar);
string stringData = Encoding.ASCII.GetString(data, 0, recv);
ListAddItem(stringData);
}
}
catch
{
}
}
答案 0 :(得分:0)
您的ns(网络流基于每个客户端)
在以下代码中,您的ns用于传入客户端。因此,您正在迭代所有客户端,但之后只与当前传入的客户端进行通信
foreach (var item in clients)
{
ns.Write(data, 0, recv);
//send message to client
}
同意@Damien_The_Unbeliever这将适用于少数客户,但当您开始扩展超过2000多个客户端时,您将遇到性能问题。通过线程切换和需要打开的端口数量。最好使用基于事件/异步的架构