Почему SendAsync не поднимает завершенное событие на моем SocketAsyncEventArgs, хотя мой сервер-сокет уже получил все байты?

78
11

Поэтому у меня очень простая настройка: сервер, ожидающий подключения клиента, и клиент, который подключается к серверу и отправляет сообщения. После этого сервер должен отправить одно и то же сообщение обратно. Но когда я пытаюсь отправить сообщение с client.SendAsync(sendArgs), он фактически не вызывает завершенное событие в объекте sendArgs, хотя я вижу, что мой сервер-сокет уже получил все байты. Итак, почему sendArgs.Completed в моем Client-Socket не поднимается, а получаетArgs.Completed в моем классе Server-Socket?

Пространства имен: 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);
}
}

спросил(а) 2021-01-25T16:58:51+03:00 4 месяца, 4 недели назад
1
Решение
140

Изменение: я исправил это. Дело в том, что я отсутствовал, чтобы проверить, завершился ли метод SendAsync синхронно или асинхронно. Если он заканчивается синхронно, мне нужно самому вызвать событие

bool completedAsync = client.SendAsync(sendArgs);
if(!completedAsync)
{
SendArgs_Completed(this, sendArgs);
}

ответил(а) 2021-01-25T16:58:51+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема