C# TCP | C |接受多个客户端并在同一端口上管理它们
我正在尝试使用TCP在同一端口上接受和管理多个客户端。 我试着使用我在谷歌上找到的一些答案,但没有一个奏效。 其主要思想是用于客户端的专用表单应用程序连接到用作侦听器的控制台应用程序。这就是我到目前为止所拥有的:C# TCP | C |接受多个客户端并在同一端口上管理它们,c#,multithreading,tcp,listener,port,C#,Multithreading,Tcp,Listener,Port,我正在尝试使用TCP在同一端口上接受和管理多个客户端。 我试着使用我在谷歌上找到的一些答案,但没有一个奏效。 其主要思想是用于客户端的专用表单应用程序连接到用作侦听器的控制台应用程序。这就是我到目前为止所拥有的: static void Main(string[] args) { try { int counter = 0; // set the TcpListener on port 13000
static void Main(string[] args)
{
try
{
int counter = 0;
// set the TcpListener on port 13000
int port = 13000;
TcpListener server = new TcpListener(IPAddress.Any, port);
// Start listening for client requests
server.Start();
// Buffer for reading data
byte[] bytes = new byte[1024];
string data;
//Enter the listening loop
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
counter += 1;
//Control each client
var t = new Thread(new ParameterizedThreadStart(AccentClient));
t.Start();
//Handle the client that just connected
handleClinet handle_client = new handleClinet();
handle_client.startClient(client, counter.ToString());
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
i = stream.Read(bytes, 0, bytes.Length);
while (i != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(String.Format("Received: {0}", data));
Console.WriteLine("Fixed: {0}", data.Replace("$", ""));
// Process the data sent by the client.
data = data.Replace("$", "") + " Bla";
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine(String.Format("Sent: {0}", data));
Console.WriteLine();
i = stream.Read(bytes, 0, bytes.Length);
}
// Shutdown and end connection
//client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.WriteLine("Hit enter to continue...");
Console.Read();
}
public static void AccentClient(object clientObj)
{
var client = clientObj as TcpClient;
}
}
//Class to handle each client request separatly
public class handleClinet
{
TcpClient clientSocket;
string clNo;
public void startClient(TcpClient inClientSocket, string clineNo)
{
this.clientSocket = inClientSocket;
this.clNo = clineNo;
Thread ctThread = new Thread(doChat);
ctThread.Start();
}
private void doChat()
{
int requestCount = 0;
byte[] bytesFrom = new byte[100000];
string dataFromClient = null;
Byte[] sendBytes = null;
string serverResponse = null;
string rCount = null;
requestCount = 0;
while ((true))
{
try
{
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, clientSocket.ReceiveBufferSize);
dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
Console.WriteLine(" >> " + "From client- " + clNo + dataFromClient);
rCount = Convert.ToString(requestCount);
serverResponse = "Server to clinet(" + clNo + ") " + rCount;
sendBytes = Encoding.ASCII.GetBytes(serverResponse);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
Console.WriteLine(" >> " + serverResponse);
}
catch (Exception ex)
{
Console.WriteLine(" >> " + ex.ToString());
break;
}
}
}
}
谢谢首先,您的AcceptClient方法并没有像现在这样做:
public static void AccentClient(object clientObj)
{
var client = clientObj as TcpClient;
}
因此,当客户端连接时,您生成的整个线程没有任何作用
其次,给定当前代码,当客户端连接时,主线程将停止侦听其他客户端,并开始与刚连接的客户端通信:
TcpClient client = server.AcceptTcpClient();
// ...
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i = stream.Read(bytes, 0, bytes.Length);
while (i != 0)
{
// ...
i = stream.Read(bytes, 0, bytes.Length);
}
因此,在当前客户端完成之前,不会接受其他客户端
第三,您不仅在主线程上接受客户机并与之通信,而且还在另一个线程上与客户机通信,同时:
handleClinet handle_client = new handleClinet();
handle_client.startClient(client, counter.ToString());
这些定义如下:
public void startClient(TcpClient inClientSocket, string clineNo)
{
// ...
Thread ctThread = new Thread(doChat);
ctThread.Start();
}
private void doChat()
{
// ...
while ((true))
{
// ...
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, clientSocket.ReceiveBufferSize);
dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
Console.WriteLine(" >> " + "From client- " + clNo + dataFromClient);
// ...
}
}
这总是无法预料地奏效
总结如下:
拆下no-op。
更改代码,使主线程只调用异步客户端处理程序。
调用异步处理程序后,确保主线程中的循环不执行任何其他操作,而是立即返回以接受下一个客户机。
那么你有什么问题?这里的问题是什么?它根本不起作用…首先,谢谢你的快速回复!第二,如果你必须选择,你会用什么?当然,AccentClien函数,在添加函数所做的事情或handleClient类之后?handleClient类是异步的,它创建另一个线程并在该线程上与客户机通信,所以我选择它。否则,下一个客户端将不得不等待前一个客户端完成。实际上,在我写了评论之后,我尝试了几件事,异步工作得最好。非常感谢。