2012-03-23 15 views
6

Utilizzando le prese, non sono sicuro di come impostare il timeout?Impostazione del timeout del socket?

grazie

int sock, connected, bytes_recieved; 
char send_data [128] , recv_data[128];  
SOCKADDR_IN server_addr,client_addr;  
int sin_size; 
int j = 0; 

::socket(AF_INET, SOCK_STREAM, 0); 

server_addr.sin_family = AF_INET;   
server_addr.sin_port = htons(4000);  
server_addr.sin_addr.s_addr = INADDR_ANY; 

::bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); 
::listen(sock, 5); 
::fflush(stdout); 

while(1) 
{ 
    sin_size = sizeof(struct sockaddr_in); 
    connected = ::accept(sock, (struct sockaddr *)&client_addr, &sin_size); 

    while (1) 
    { 
     j++; 

     ::send(connected, send_data, strlen(send_data), 0); 

     //dealing with lost communication ? 
     //and reastablishing communication 
     //set timeout and reset on timeout error  
    } 
} 
::closesocket(sock); 

risposta

5

Una presa è in modalità di blocco per impostazione predefinita. Se si passa alla modalità non-blocking con ioctlsocket(FIONBIO), è possibile utilizzare per gestire select() timeout:

SOCKET sock, connected; 
int bytes_recieved; 
char send_data [128] , recv_data[128];   
SOCKADDR_IN server_addr,client_addr;  
int sin_size; 
int j = 0, ret; 
fd_set fd; 
timeval tv; 

sock = ::socket(AF_INET, SOCK_STREAM, 0); 

server_addr.sin_family = AF_INET;   
server_addr.sin_port = htons(4000);  
server_addr.sin_addr.s_addr = INADDR_ANY; 

::bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); 
::listen(sock, 1); 
::fflush(stdout); 

u_long nbio = 1; 
::ioctlsocket(sock, FIONBIO, &nbio); 

while(1) 
{ 
    FD_ZERO(&fd); 
    FD_SET(sock, &fd); 

    tv.tv_sec = 5; 
    tv.tv_usec = 0; 

    if (select(0, &fd, NULL, NULL, &tv) > 0) 
    { 
     sin_size = sizeof(struct sockaddr_in); 
     connected = ::accept(sock, (struct sockaddr *)&client_addr, &sin_size); 

     nbio = 1; 
     ::ioctlsocket(connected, FIONBIO, &nbio); 

     while (1) 
     { 
      j++; 

      if (::send(connected, send_data, strlen(send_data), 0) < 0) 
      { 
       //dealing with lost communication ? 
       //and reastablishing communication 
       //set timeout and reset on timeout error  

       if (WSAGetLastError() == WSAEWOULDBLOCK) 
       { 
        FD_ZERO(&fd); 
        FD_SET(connected, &fd); 

        tv.tv_sec = 5; 
        tv.tv_usec = 0; 

        if (select(0, NULL, &fd, NULL, &tv) > 0) 
         continue; 
       } 

       break; 
      } 
     } 

     closesocket(connected); 
    } 
} 
+0

domanda: selezionare (0, NULL, & set, NULL, & tv) dove "set" è un "int" ma per "fd_set" vuole ... SOCKET fd_array [FD_SETSIZE];/* un array di SOCKET */Non sto usando quel tipo, quindi come faccio ad aggirare questo? thx – jdl

+0

Scusa, mia cattiva. L'ho corretto –

5

è necessario utilizzare setsockopt per impostare le opzioni SO_SNDTIMEO e/o SO_RCVTIMEO.

1

è possibile utilizzare:

fd_set fd; 
timeval tv; 
FD_ZERO(&fd); 
FD_SET(sock, &fd); 
tv.tv_sec = time_out(second); 
tv.tv_usec = 0; 

per impostare il timeout per l'invio, la ricezione di dati.

Problemi correlati