2016-05-11 2 views
0

Пожалуйста, кто-то любезно поможет мне, как поймать ошибку операции сокета из класса CAsyncSocket.Использование CAsynSocket, как убрать код выхода сокетов?

Если я это сделать:

int iLen = recv(socket, socketBuffer, sizeBuffer, 0); 
if(iLen==SOCKET_ERROR) { 
    //handle error here 
} else { 
    //do something with the received data 
} 

Он всегда возвращает ошибку, которая WSAEWOULDBLOCK, и то же самое для другой операции, как Send(), Connect(), и т.д. ...
Согласно MSDN , это не фатальная ошибка, и для завершения действий должно пройти некоторое время.

Итак, как я могу проверять каждый раз, когда моя программа правильно выполнила recv() или send()?

+0

Последний аргумент [ 'recv'] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121 (v = vs.85) .aspx) - это значение флага целого числа *, а не указатель. Поэтому вы не должны использовать 'NULL'. –

+0

Что касается вашей проблемы, 'WSAEWOULDBLOCK' просто говорит вам, что в * неблокирующем * соке нет ничего. Вы можете использовать ['select'] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms740141 (v = vs.85) .aspx) или [' WSAPoll'] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms741669(v=vs.85).aspx), чтобы опросить, есть ли сокет (ы) для чтения. –

+0

Спасибо за ваш комментарий, в MFC они определяют NULL как 0; однако, я действительно редактировал свой код в качестве вашего предложения. Для select() я до сих пор не знаю, как его использовать. –

ответ

1

Прежде всего не следует смешивать CAsyncSocket API и Berkley сокетов API.

Ваш OnReceive обработчик должен выглядеть следующим образом:

CByteArray InBuffer; 
    InBuffer.SetSize(DEFAULT_RX_BUFFER_SIZE);  
    int nBytes = Receive(InBuffer.GetData(), (int)InBuffer.GetSize()); 

    switch (nBytes) 
    { 
     case 0: 
      ShutDown(CAsyncSocket::both); 
      break; 
     case SOCKET_ERROR: 
      if (::GetLastError() != WSAEWOULDBLOCK) 
       ShutDown(CAsyncSocket::both); 
      else 
       AsyncSelect(); 
      break; 
     default: 
      { 
       // TODO: data processing goes here 
      } 
      break; 
    } 
+0

Спасибо за ваш комментарий. Поэтому я должен сделать то же самое для Send(), Listen() и Connect()? Btw, где определено значение DEFAULT_RX_BUFFER_SIZE? Я не могу найти его. –

+0

Да, есть 'OnConnect',' OnSend' и другие обработчики. Обработка ошибок почти такая же. Константа 'DEFAULT_RX_BUFFER_SIZE' определяется пользователем. –

+0

Я знаю, что это не вопрос, но он совершенно другой, чем я ожидаю. Как я могу получить только первые 4 байта целого? Потому что, когда я отправил, я на самом деле упаковал 2 данных. Первый - int, а второй - char *. Когда я применил ваш код, он вытащил все в 'default:' –

 Смежные вопросы

  • Нет связанных вопросов^_^