c# - 为什么即使我的 Server-Socket 已经收到所有字节,SendAsync 也不会在我的 SocketAsyncEventArgs 上引发 Completed 事件?
问题描述
所以我有一个非常简单的设置:一个等待客户端连接的服务器和一个连接到服务器并发送消息的客户端。服务器随后应再次发回相同的消息。但是当我尝试使用client.SendAsync(sendArgs)发送消息时,它实际上并没有在 sendArgs 对象上调用 Completed 事件,即使我可以看到我的 Server-Socket 已经接收到所有字节。那么为什么我的Client-Socket中的sendArgs.Completed没有被提升,而是在我的Server-Socket类中的receiveArgs.Completed呢?
使用的命名空间:System、System.Net、System.Net、System.Text
到目前为止,这是我的代码:
客户
public class SocketClient
{
public IPEndPoint Endpoint { get; }
private Socket client;
public SocketClient(IPAddress address, int port)
{
Endpoint = new IPEndPoint(address, port);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void ConnectToServer(IPAddress serverAddress, int serverPort)
{
client.Bind(Endpoint);
try
{
client.Connect(serverAddress, serverPort);
}
catch (SocketException)
{
return;
}
}
public void SendMessage(string message)
{
SocketAsyncEventArgs sendArgs = new SocketAsyncEventArgs();
byte[] buffer = Encoding.ASCII.GetBytes(message);
sendArgs.SetBuffer(buffer, 0, buffer.Length);
sendArgs.Completed += SendArgs_Completed;
client.SendAsync(sendArgs);
}
private void SendArgs_Completed(object sender, SocketAsyncEventArgs e)
{
SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs();
byte[] buffer = new byte[1024];
receiveArgs.SetBuffer(buffer, 0, buffer.Length);
receiveArgs.Completed += ReceiveArgs_Completed;
client.ReceiveAsync(receiveArgs);
}
private void ReceiveArgs_Completed(object sender, SocketAsyncEventArgs e)
{
string message = Encoding.ASCII.GetString(e.Buffer);
Console.WriteLine(message);
}
}
服务器
public class SocketServer
{
public IPEndPoint Endpoint { get; }
private Socket server;
public SocketServer(IPAddress address, int port)
{
Endpoint = new IPEndPoint(address, port);
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void Start()
{
server.Bind(Endpoint);
server.Listen(10);
SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs();
acceptArgs.Completed += AcceptArgs_Completed;
server.AcceptAsync(acceptArgs);
}
private void AcceptArgs_Completed(object sender, SocketAsyncEventArgs e)
{
Socket connectionSocket = e.AcceptSocket;
SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs();
byte[] buffer = new byte[1024];
receiveArgs.SetBuffer(buffer, 0, buffer.Length);
receiveArgs.Completed += ReceiveArgs_Completed;
connectionSocket.ReceiveAsync(receiveArgs);
e.AcceptSocket = null;
server.AcceptAsync(e);
}
private void ReceiveArgs_Completed(object sender, SocketAsyncEventArgs e)
{
Socket connectionSocket = (Socket)sender;
SocketAsyncEventArgs sendArgs = new SocketAsyncEventArgs();
sendArgs.SetBuffer(e.Buffer, 0, e.Buffer.Length);
connectionSocket.SendAsync(sendArgs);
connectionSocket.ReceiveAsync(e);
}
}
解决方案
编辑:我修好了。我缺少的是检查SendAsync方法是同步完成还是异步完成。如果它同步完成,我需要自己调用事件
bool completedAsync = client.SendAsync(sendArgs);
if(!completedAsync)
{
SendArgs_Completed(this, sendArgs);
}
推荐阅读
- dart - 遍历 Dart 中的类列表
- r - 在分组后在 R 中使用 Levene 测试时出错 [错误:不是数字变量]
- r - R 重复行的连接类型
- azure - 带有 agic 的 Azure AKS - 如何使用 Terraform 创建它?
- html - 从草稿 js 编辑器导出 html 并保持样式
- go - 如何使用 Go 将文档 ID 作为字段值 Firestore 插入
- php - 如何在最短的时间内将 20k xml 文件数据保存到 codeigniter 中的 mysql?
- scala - 从列表中创建加特林馈线
- automated-tests - 空手道 - 如何将变量值放入驱动程序配置(在 JS 中配置,在特性中读取值 - 背景)
- mongodb - 从 MongoDB 中的所有文档中获取数组字段的第一个元素的总和