почему при записи в сокет более одного раза он блокируется? - PullRequest
0 голосов
/ 11 января 2010

У меня проблема с сокетом, и я был бы рад, если бы вы могли помочь ...
Проблема в том, что когда я отправляю данные более одного раза, они блокируются, например:

//--- client ---  
//..
send(sock, buf_1, sizeof(buf_1), 0);  

for (x10){   
//...  
send(sock, buf_2, sizeof(buf_2), 0);    
if (recv(sock, buf_2, sizeof(buf_2), 0)<0) printf("recv_2() failed");   
//...   
}  

for (x20){   
//...  
send(sock, buf_3, sizeof(buf_3), 0);     
if (recv(sock, buf_3, sizeof(buf_3), 0)<0) printf("recv_3() failed");   
//...    
}  
//...          

//--- server---   
//...  
if (recv(sock, buf_1, sizeof(buf_1), 0)<0) printf("recv_1() failed"); 

for (x10){     
if (recv(sock, buf_2, sizeof(buf_2), 0)<0) printf("recv_2() failed");    
//...    
send(sock, buf_2, sizeof(buf_2), 0);     
}     

for (x20){   
if (recv(sock, buf_3, sizeof(buf_3), 0)<0) printf("recv_3() failed");   
//...    
send(sock, buf_3, sizeof(buf_3), 0);     
}     
//...   

обменные блоки сразу после первого send(), есть идея?
Поддерживает ли udp также несколько sendto()?

Спасибо за ваш ответ -

Ответы [ 2 ]

3 голосов
/ 11 января 2010

В этом случае и send, и recv блокируются. Вам нужно установить асинхронный флаг (я думаю, O_NONBLOCK - см. Документацию по fnctl) на сокете. Но это может быть сложно получить право. Если вы не отправляете / не получаете все данные, которые вы должны продолжать вызывать send / recv, пока не получите все это, и эффективное выполнение этого означает, что вам придется использовать системный вызов select на ваших сокетах.

Теперь все это вполне осуществимо, но не так весело и мучительно для отладки. Я рекомендую вам попробовать библиотеку boost :: asio (asynchronous io), а не играть с необработанными сокетами. http://www.boost.org/doc/libs/1_41_0/doc/html/boost_asio.html

1 голос
/ 11 января 2010

UDP или TCP?

Если TCP; насколько велики данные, которые вы отправляете. Что делает клиент? Клиент действительно получает и обрабатывает первый блок данных? Что МОЖЕТ происходить, так это то, что второй вызов отправки блокируется, потому что окно приема вашего клиента заполнено, а стеки TCP задействованы в управлении потоком, что заставляет вашу синхронную отправку блокировать в ожидании, что одноранговое устройство считывает достаточно данных, чтобы окно recv не полный и ситуация с контролем потока прошла ...

Также обратите внимание, что если вы имеете дело с TCP, то recv вызывает CAN и будет возвращать любое количество байтов от 1 до количества отправленных вами байтов; Вы всегда должны делать цикл, чтобы накапливать количество байтов, которое, по словам вашего фрейма сообщения, вам нужно ...

В конце вашего вопроса вы упомянули про UDP и несколько sendTos, как это связано с вашим вопросом? Вы действительно используете здесь UDP-сокеты?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...