我有一个问题,有关通过C#通过网络流从TCPListener服务器向客户端发送和接收消息。现在,我的TCPListener实例可以从客户端接收一条消息并将其写入服务器控制台,并且可以接受一个输入字符串并将其发送回客户端。但我希望改进该功能,以接受来自客户端的多个连续消息并将多个连续响应发送回客户端。如果NetworkStream的ReadAsync和WriteAsync函数可以处理接收多个连续的消息或发送多个连续的消息,并且有更好的方法可以实现,那么是否有人碰巧拥有任何指针?另外,由于Console.ReadLine函数将在服务器从未从ReadLine接收到任何用户输入(并且没有按Enter键)的情况下阻塞,是否有办法测试键盘是否有可选的用户输入?这样,仅当服务器从用户那里收到某种控制台输入时,我才能尝试执行send message命令,否则可以继续接收客户端消息。
public static async Task getMessage(TcpListener server)
{
byte[] bytes = new byte[256];
using (var theStream = await server.AcceptTcpClientAsync())
{
using (var tcpStream = theStream.GetStream())
{
await tcpStream.ReadAsync(bytes, 0, bytes.Length);
var msg = Encoding.UTF8.GetString(bytes);
Console.WriteLine(msg);
var payload = Console.ReadLine();
var bytes2 = Encoding.UTF8.GetBytes(payload);
await tcpStream.WriteAsync(bytes2, 0, bytes2.Length);
}
}
}
很有趣的是,看到一个仅用于一个客户端的服务器实现!
TCP是一种双向通信协议,因此,可以,您当然可以发送所需的内容,并在需要时同时接收任何内容。
我试图在源代码中添加评论以使其自我解释。
但是关键是将TcpClient
和NetworkStream
实例声明为静态变量,以便主线程(从控制台读取并将有效载荷发送到客户端的线程可以访问它们)
希望这会有所帮助。
public static async Task getMessage(TcpListener server)
{
byte[] bytes = new byte[256];
using (theStream = await server.AcceptTcpClientAsync())
{
using (tcpStream = theStream.GetStream())
{
// We are using an infinite loop which ends when zero bytes have been received.
// Receiving zero bytes means the transmission is over (client disconnected)
while (await tcpStream.ReadAsync(bytes, 0, bytes.Length) > 0)
{
var msg = Encoding.UTF8.GetString(bytes);
Console.WriteLine(msg);
}
Console.WriteLine("Client has disconnected");
}
}
}
/// <summary>
/// Transmists the payload to the client
/// </summary>
/// <param name="payload">The payload to transmit to the client</param>
/// <returns></returns>
static async Task Transmit(string payload)
{
var bytes2 = Encoding.UTF8.GetBytes(payload);
await tcpStream.WriteAsync(bytes2, 0, bytes2.Length);
}
// We are declaring the TcpClient and NetworkStream as static variables
// to be able to access them from all the threads.
private static TcpClient theStream;
public static NetworkStream tcpStream;
static void Main(string[] args)
{
TcpListener server = new TcpListener(IPAddress.Loopback, 9876);
server.Start();
// Start the task getMessage() to accept a client and receive
Task.Run(() => getMessage(server));
string payload;
while ((payload = Console.ReadLine()) != "exit")
{
// Check if the client has connected.
if (tcpStream != null)
{
// Check if they are still connected
if (theStream.Client.Connected)
{
Task.Run(() => Transmit(payload));
}
else
{
Console.WriteLine("the client connection is lost");
break;
}
}
else
{
Console.WriteLine("The client has not connected yet.");
}
}
Console.WriteLine("Stopping the server");
server.Stop();
}