2016-09-07 2 views
1

Ih, Я думаю, что мой код является правильным, но он не работает :(Установите тайм-аут для RECV с розетки на Windows,

Чтобы установить тайм-аут для функции Recv на окна я знаю, я должен использовать этот код: .

    DWORD timeout = 2000; 

       if (setsockopt(listenSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(DWORD))) 
       { perror("setsockopt"); 
       return -1; 
       } 

Но это не работает

код моего сервера:

SOCKET listenSocket; 
SOCKET remoteSocket= INVALID_SOCKET; 
SOCKADDR_IN Server_addr; 
SOCKADDR_IN Client_addr; 
int sin_size; 
short port; 

int wsastartup; 
int ls_result; 
WORD wVersionRequested = 0x0202; 
WSADATA wsaData; 

wsastartup = WSAStartup(wVersionRequested, &wsaData); 
if (wsastartup != NO_ERROR) cout << "Errore WSAStartup()" << endl; 

listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

port = 4000; 
Server_addr.sin_family = AF_INET; 
Server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 

Server_addr.sin_port = htons(port); 

if (bind(listenSocket,(LPSOCKADDR) &Server_addr,sizeof(struct sockaddr)) < 0) { 
    cout << "Server: error bind." << endl; 
closesocket(listenSocket); 
return -1; 
} 

ls_result = listen(listenSocket, SOMAXCONN); 

sin_size = sizeof(struct sockaddr_in); 
remoteSocket = accept(listenSocket, (struct sockaddr *) &Client_addr, &sin_size); 

// SET THE TIME OUT 
DWORD timeout = 300; 
if (setsockopt(remoteSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(DWORD))) 
{ perror("setsockopt"); 
    return -1; 
} 

int i=0; 
while (i<50){ 
    t_start = clock(); 

    // when client receives the send below it wait 3 seconds and then trasmits the answer 
    send(remoteSocket, "code of start transmission", sizeof("code of start transmission"), 0); 

    recv_size=recv(remoteSocket, messaggio, sizeof(messaggio), 0); 

    printf("time for read= %f second \n", ((double)(end - t_start))/CLOCKS_PER_SEC); 

    i=i+1; 
} 

Клиент, получая сообщение «код начала передачи» с серверов, ожидает 3 секунды, а затем переходит к серверу. Я ожидаю, что время чтения составляет 300 мс и recv_size < 0, вместо recv_size < 0, но время для чтения составляет более 1,5 секунд (сервер ждет сообщения клиента). Я не понимаю, почему.

Я нахожусь в окнах, и я использую eclipse и mingw-w64.

Пожалуйста, кто-нибудь может мне помочь?

ответ

1

Чтобы установить тайм-аут для функции Recv на окнах я знаю, что я должен использовать этот код:

   DWORD timeout = 2000; 

      if (setsockopt(listenSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(DWORD))) 
      { perror("setsockopt"); 
      return -1; 
      } 

Нет, это должно быть int, не DWORD, но основная проблема заключается в том, что youre здесь устанавливают тайм-аут accept(), так как это гнездо для прослушивания. Вам нужно установить его на приемник (ы).

+0

Я считаю, что он наследуется практически во всех современных реализациях. Но я бы определенно попытался установить его на отдельном сокете, чтобы убедиться, что это не хорошо документировано. –

+0

В Windows это обязательно должно быть 'DWORD', а не' int'. В документации [MSDN] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms740532.aspx) указано столько же. –

1

Ваш код пытается использовать сокет после его выключения. Это не очень хорошая идея, потому что сокет все еще находится где-то посреди неудачной операции блокировки и не имеет никакой формы для запуска новой операции. Невозможно размотать части ранее выполненной операции и поставить сокет обратно там, где он был до начала работы.

После того, как операция блокировки гнезда отключилась, все, что вы можете сделать, это закрыть розетку. Нет поддержки для отмены операции, которая частично завершена и оставила сокет в каком-либо нормальном состоянии.

Если отправить или получить время срабатывания на сокете, состояние сокета неопределенно, и не должно быть использовано [.] - опция сокета MSDN

SO_RCVTIMEO никогда не должен использоваться в код, предназначенный для работы с сокетами. Это kludge, чтобы предотвратить бесконечные ожидания в коде, который не был предназначен для работы с сокетами изначально. Это не дроиды, которые вы ищете.

+0

Спасибо за ответ. Я буду изменять свой код с учетом вашего комментария. – cerry92

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