Linux Перекрывающийся сервер сокетов TCP ввода-вывода не отвечает правильно C # ASync Client

Я пытаюсь закодировать простой работающий клиент/сервер эхо-сокета. Мне удалось заставить работать синхронный сервер с клиентом, но теперь мне нужен асинхронный.

Если я использую версии Microsoft, они работают хорошо, ASync Server:

https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.110).aspx

Клиент Microsoft ASync:

https://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

Сейчас я пытаюсь заставить Microsoft Async Client взаимодействовать с Linux C++ Overlapped I/O Server:

http://www.tutorialized.com/tutorial/Linux-C-Overlapped-Server-and-Client-Socket-Example/77220

Тут начинаются проблемы. Соединение установлено, и я могу отправить сообщение на сервер, сервер отвечает, возвращая сообщение (в соответствии с выводом отладки и терминала), но клиент Microsoft ASync никогда не получает ответ на свой сокет.

Нельзя ли подключить асинхронный клиент к серверу перекрывающегося ввода-вывода? Я не уверен, почему ответ от сервера никогда не доходит до клиента. Отладка клиента Microsoft ASync сообщает мне, что функция Receive никогда не передает эту строку кода:

receiveDone.WaitOne();

ReceiveDone — это событие ManualResetEvent:

private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);

Контекст:

// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();

Вот функция обратного вызова для получения, устанавливающая receiveDone по завершении. bytesRead никогда не превышает 0.:

private void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        // Retrieve the state object and the client socket 
        // from the asynchronous state object.
        StateObject state = (StateObject)ar.AsyncState;
        Socket client = state.workSocket;

        // Read data from the remote device.
        int bytesRead = client.EndReceive(ar);

        if (bytesRead > 0)
        {
            // There might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

            // Get the rest of the data.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        else
        {
            // All the data has arrived; put it in response.
            if (state.sb.Length > 1)
            {
                response = state.sb.ToString();
            }
            // Signal that all bytes have been received.
            receiveDone.Set();
        }
    }
    catch (Exception e)
    {
        msg("Fail ReceiveCallback: " + e.Message, false);
    }
} 

В любом случае, этот код работает при подключении к серверу ASync, но не к серверу перекрывающегося ввода-вывода, поэтому на самом деле я спрашиваю, что нужно изменить в Перекрывающийся код сервера ввода-вывода, чтобы он отправлял обратно сообщения, которые может получать клиент ASync?

Это вывод сервера, если он отправлен Hello World из клиента ASync:

root@deb7sve:/home/petlar/Host/SockServer# g++ OverlappedServer.cpp -o os.out -lpthread
root@deb7sve:/home/petlar/Host/SockServer# ./os.out
---------------------
Received connection from 10.0.2.2
Read 13 bytes from 4
Sent 13 bytes to 4

person Plarsen    schedule 19.04.2015    source источник
comment
Этот код не является асинхронным, так как предполагается, что поток ожидает события. Это бессмысленный образец кода MSDN. Вы получаете ужасный асинхронный код и не получаете никаких преимуществ.   -  person usr    schedule 19.04.2015
comment
Закрывает ли сервер соединение после завершения отправки?   -  person usr    schedule 19.04.2015
comment
Я не уверен, что пример Microsoft является хорошим асинхронным примером, но я попытаюсь улучшить клиент позже, как только будет установлена ​​простая связь с сервером. Нет, сервер ждет дополнительных пакетов и возвращает их клиенту. До 100 клиентов, если я правильно прочитал код, но в примере кода не хватает очистки и повторного использования сокетов и т. д., так что это очень просто.   -  person Plarsen    schedule 19.04.2015


Ответы (1)


Этот клиентский код устанавливает событие только при закрытии соединения. Согласно вашему комментарию сервер не закрывает соединение. Вот почему событие никогда не устанавливается.

Выбросьте клиентский код и перепишите его, используя простой синхронный код. 50% вашего кода посвящено созданию асинхронного ввода-вывода (неработающим способом). Асинхронный ввод-вывод не предназначен для повышения эффективности сети. Это нужно для экономии ресурсов потока. Скорее всего, это не нужно на клиенте.

person usr    schedule 19.04.2015
comment
Никогда не думал, что клиент ждет закрытия соединения. Я учту это, спасибо! - person Plarsen; 19.04.2015
comment
Отлично, сработало! Как только я протестировал закрытие серверной части сокета после эхо-ответа, на клиенте появилось эхо-сообщение. Хорошо, теперь я понимаю, что клиентский код нужно освежить, спасибо! - person Plarsen; 19.04.2015