7 Stimmen

Die Socket-Timeout-Einstellung setzen?

Bei der Verwendung von Sockets bin ich mir nicht sicher, wie ich das Timeout einstellen soll?

Danke

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 reestablishing communication
        // set timeout and reset on timeout error
    }
}
::closesocket(sock);

8voto

Jon Punkte 411383

Sie müssen setsockopt verwenden, um die Optionen SO_SNDTIMEO und/oder SO_RCVTIMEO festzulegen.

7voto

Remy Lebeau Punkte 498719

Ein Sockel ist standardmäßig im Blockiermodus. Wenn Sie ihn in den nicht blockierenden Modus mit ioctlsocket(FIONBIO) umschalten, können Sie select() verwenden, um Zeitüberschreitungen zu verwalten:

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

1voto

The Bird Punkte 397

Sie können verwenden:

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

um eine Timeout für das Senden und Empfangen von Daten festzulegen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X