WSAEWOULDBLOCK –
возникает в результате когда принимающая сторона не успевает обработать буфер данных.
Решить проблему можно, отлавливая событие FD_WRITE;
Наиболее опасная ситуация возникает на стороне сервера. Например, рассмотрим
такой код на стороне сервера:
bool WriteData(SOCKET hSocket,
char * cbBuff,
int nSize)
{
int MaxByteSend = nSize;
int Offset = 0;
int nError = 0;
do
{
nError = send(hSocket, cbBuff + Offset, MaxByteSend, 0);
if(nError
<= 0)
{
nError = WSAGetLastError();
if(nError
== WSAEWOULDBLOCK)
{
printf("WriteData WSAEWOULDBLOCK\r\n");
continue;
}
else return false;
}
if(nError
> 0)
{
Offset += nError;
MaxByteSend -= nError;
}
}
while(nError > 0 && MaxByteSend != 0);
return Offset
== nSize ? true : false;
}
На 1-ый взгляд не
каких проблем, если возникает событие WSAEWOULDBLOCK то мы просто пробуем еще раз отправить данные. Но в этом-то
и заключается вся суть проблемы! Во 1-ых сторона клиента может в этот момент не
принимать данные, а обрабатывать предыдущую порцию. Сервер же будет золочен на
срок, пока клиент не примет буфер! Как способ
выхода из данной ситуации, можно ввести переменную nTryCount = 0; и если мы получаем WSAEWOULDBLOCK увеличиваем nTryCount++; когда количество таких, попыток подряд достигнет
N(например 3), завершаем процедуру отправки с кодом неудачи!...Далее
когда SOCKET будет готов читать данные, мы получим событие FD_WRITE. И дошлем остальную часть буфера!
Второе решение проблемы это использовать полностью асинхронные
сокеты.
Комментариев нет:
Отправить комментарий