2015-04-19 6 views
0

Я пытаюсь закодировать простой функционал echo socket client/server. Мне удалось получить синхронный сервер с клиентом для работы, но теперь мне нужен асинхронный.Linux Overlapped I/O TCP-сервер сокетов не отвечает на корректность клиента C# ASync

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

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

Microsoft ASync Client:

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

То, что я пытаюсь в настоящее время является get Клиент Microsoft Async Communica т.е с/O Server Linux C++ Overlapped I:

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

Здесь начинаются проблемы. Соединение установлено, и я могу отправить сообщение на Сервер, сервер отвечает на эхо-сообщение (в соответствии с отладочной и выводной информацией), но клиент ASync 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(); 

Вот функция обратного вызова для приема, при необходимости устанавливая метод приема приема. 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 серверу, но не сервер Overlapped ввода/вывода, так что на самом деле я прошу, что изменить в Overlapped I/O server code, для него отправлять сообщения, которые может получить ASync-клиент?

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

[email protected]:/home/petlar/Host/SockServer# g++ OverlappedServer.cpp -o os.out -lpthread 
[email protected]:/home/petlar/Host/SockServer# ./os.out 
--------------------- 
Received connection from 10.0.2.2 
Read 13 bytes from 4 
Sent 13 bytes to 4 
+0

Этот код не является асинхронным, так как предположительно поток ожидает событие. Это бессмысленный образец кода MSDN. Вы получаете ужасный асинхронный код и не получаете никаких преимуществ. – usr

+0

Является ли сервер закрытием соединения, когда он будет отправлен? – usr

+0

Я не уверен, что пример Microsoft - хороший асинхронный пример, но я попробую улучшить клиент позже, как только будет установлена ​​простая связь с сервером. Нет, сервер ждет больше пакетов и повторяет их обратно клиенту. До 100 клиентов, если я правильно прочитал код, но в образце кода не хватает очистки и повторного использования сокетов и т. Д., Поэтому это очень просто. – Plarsen

ответ

1

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

Удалите код клиента и перепишите его с помощью простого синхронного кода. 50% вашего кода посвящено созданию async IO (сломанным способом). Async IO не занимается повышением эффективности сети. Здесь можно сохранить ресурсы потоков. Скорее всего, это не нужно на клиенте.

+0

Никогда не думал, что Клиент ждет завершения соединения. Я буду считать это, спасибо! – Plarsen

+0

Отлично, это сработало! Как только я протестировал закрытие сервера сокетов после ответа эха, эхо-сообщение появилось на клиенте. Хорошо, теперь я понимаю, что клиентский код нужно почистить, спасибо! – Plarsen