C# 接收命令时通过TCP发送字符串

C# 接收命令时通过TCP发送字符串,c#,winforms,tcp,reader,C#,Winforms,Tcp,Reader,我正在做一个阅读程序。它基于Winorms 我需要一个代码,winform将通过TCP(端口3573)按需发送一些数据。(我所说的请求是指当程序通过TCP接收到命令GET时 我是一个新手,所以这个主题看起来很难将所有这些结合起来:线程、TCPRead TCP Send、事件处理程序 所以我需要一个完整的代码或示例来帮助我如何实现它 我尝试了一些来自internet的示例代码,但都不起作用(线程、TCPreader和TCPsender、TCPreaded的事件处理) 在TCP阅读器上,我们接收GE

我正在做一个阅读程序。它基于Winorms

我需要一个代码,winform将通过TCP(端口3573)按需发送一些数据。(我所说的请求是指当程序通过TCP接收到命令GET时

我是一个新手,所以这个主题看起来很难将所有这些结合起来:线程、TCPRead TCP Send、事件处理程序

所以我需要一个完整的代码或示例来帮助我如何实现它

我尝试了一些来自internet的示例代码,但都不起作用(线程、TCPreader和TCPsender、TCPreaded的事件处理)


在TCP阅读器上,我们接收GET,然后发送一些字符串,让我们通过TCP发送者说“hello world”

套接字很难正确使用,而且API非常糟糕。因为这只是在问错误,所以我建议使用“pipelines”API,它与现代的
异步
代码更加一致,更容易正确使用(而且在帧处理方面有更好的选择)

请注意,这需要Pipelines.Sockets.nonofficial,它位于nuget via上:


(添加此项将自动添加所需的所有其他部件)

使用pipeline.Sockets.non-official;
使用制度;
使用系统IO管道;
Net系统;
使用系统文本;
使用System.Threading.Tasks;
静态类程序
{
静态异步任务Main()
{
var endpoint=新的IPEndPoint(IPAddress.Loopback,9042);
Console.WriteLine(“[server]启动服务器…”);
使用(var server=new MyServer())
{
监听(端点);
Console.WriteLine(“[server]正在启动客户端…”);
任务读取器;
使用(var client=await SocketConnection.ConnectAsync(端点))
{
reader=Task.Run(()=>showincingdataasync(client.Input));
等待WriteAsync(client.Output,“hello”);
等待WriteAsync(client.Output,“world”);
Console.WriteLine(“按[返回]”);
Console.ReadLine();
}
等待读者;
server.Stop();
}
}
专用静态异步任务ShowIncomingDataAsync(PipeReader输入)
{
尝试
{
while(true)
{
var read=wait input.ReadAsync();
var buffer=read.buffer;
if(buffer.IsEmpty&&read.IsCompleted)break;//EOF
WriteLine($“[client]接收到{buffer.Length}字节;标记已消耗”);
foreach(缓冲区中的var段)
{//通常只有一个段,但可能更复杂
Console.WriteLine(“[client]”加Program.getascistring(segment.Span));
}
input.AdvanceTo(buffer.End);/“我们都吃了”
}
}
捕获{}
}
专用静态异步任务WriteAsync(PipeWriter输出,字符串负载)
{
var bytes=Encoding.ASCII.GetBytes(有效负载);
等待输出。WriteAsync(字节);
}
内部静态不安全字符串GetAscistring(只读span span)
{
固定(字节*b=span)
{
返回Encoding.ASCII.GetString(b,span.Length);
}
}
}
类MyServer:SocketServer
{
受保护的覆盖任务OnClientConnectionedAsync(在ClientConnection客户端中)
=>运行客户端(客户端);
专用异步任务RunClient(客户端连接客户端)
{
Console.WriteLine($“[server]新客户端:{client.RemoteEndPoint}”);
等待ProcessRequests(client.Transport);
WriteLine($“[server]结束的客户端:{client.RemoteEndPoint}”);
}
专用异步任务ProcessRequests(IDuplexPipe传输)
{
尝试
{
var输入=transport.input;
var输出=传输输出;
while(true)
{
var read=wait input.ReadAsync();
var buffer=read.buffer;
if(buffer.IsEmpty&&read.IsCompleted)break;//EOF
WriteLine($“[server]接收到{buffer.Length}字节;返回它,并标记为已使用”);
foreach(缓冲区中的var段)
{//通常只有一个段,但可能更复杂
Console.WriteLine(“[server]”加Program.getascistring(segment.Span));
等待输出。WriteAsync(段);
}
input.AdvanceTo(buffer.End);/“我们都吃了”
}
}
捕获{}
}
}
我可以用原始套接字编写这篇文章,但是需要更多的代码来展示最佳实践和避免问题——所有这些丑陋都已经隐藏在“管道”中了

输出:

[server] Starting server...
[server] Starting client...
[server] new client: 127.0.0.1:63076
press [return]
[server] Received 5 bytes; returning it, and marking consumed
[server] hello
[server] Received 5 bytes; returning it, and marking consumed
[client] Received 5 bytes; marking consumed
[client] hello
[server] world
[client] Received 5 bytes; marking consumed
[client] world

套接字真的很难找到正确的接口,而API只是…令人讨厌。因为这只是在问错误,我建议使用“管道”API,它更符合现代的
async
代码,更容易找到正确的接口(并且在帧处理方面有更好的选择)

请注意,这需要Pipelines.Sockets.nonofficial,它位于nuget via上:


(添加此项将自动添加所需的所有其他部件)

使用pipeline.Sockets.non-official;
使用制度;
使用系统IO管道;
Net系统;
使用系统文本;
使用System.Threading.Tasks;
静态类程序
{
静态异步任务Main()
{
var endpoint=新的IPEndPoint(IPAddress.Loopback,9042);
Console.WriteLine(“[server]启动服务器…”);
使用(var server=new MyServer())
{
监听(端点);
Console.WriteLine(“[server]正在启动客户端…”);
任务读取器;
使用(var client=await SocketConnection.ConnectAsync(端点))
{
reader=Task.Run(()=>showincommin