7
votes

Définir le délai d'attente de socket?

Utiliser des sockets, je ne sais pas comment définir le délai d'attente?

Merci P>

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);


0 commentaires

3 Réponses :


8
votes

Vous devez utiliser setSockopt < / code> pour définir le SO_SNDTTIMEO et / ou SO_RCVTimeo Options.


0 commentaires

7
votes

Une prise est en mode blocage par défaut. Si vous le basculez en mode non bloquant en utilisant ioctlsocket (fionbio) code>, vous pouvez utiliser sélectionner () code> pour gérer les délais d'attente:

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);
    } 
}


1 commentaires

Question: SELECT (0, NULL, ET SET, NULL, ET TV) Où "SET" est un "INT" mais pour "FD_SET", il veut ... socket fd_array [fd_setsize]; / * Un tableau de sockets * / Je n'utilise pas ce type alors comment puis-je contourner cela? Merci



1
votes

Vous pouvez utiliser:

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


0 commentaires