Red de conocimientos turísticos - Información de alquiler - Acerca de la función de conexión en winsock2

Acerca de la función de conexión en winsock2

Cómo configurar el tiempo de espera de conexión en Socket

AntGhazi/2001.12.14 Página de inicio: antghazi.yeah.net

He puesto patas arriba CSDN y Yahoo chino abajo. No he encontrado un método satisfactorio sobre cómo configurar el tiempo de espera de conexión del socket. Hay muchos hermanos que han hecho esta pregunta. Aquí hablaré sobre cómo configurar el tiempo de espera de conexión del socket.

Configurar el tiempo de espera de la conexión es muy simple. Alguien en CSDN también mencionó el uso de select, pero no hay una respuesta satisfactoria y completa. De lo que estoy hablando es de la función de selección. Esta función está integrada en winsock1.1. En pocas palabras, "permite que las aplicaciones que desean evitar ser bloqueadas durante las llamadas de socket adopten una forma ordenada de administrar múltiples sockets al mismo tiempo. tiempo" (palabras originales de "Tecnología de programación de redes de Windows"). Para conocer el uso y la explicación, consulte "Tecnología de programación de redes de Windows".

Antes de usar esta función, debe configurar el socket en modo sin bloqueo, de modo que se omita inmediatamente al conectarse. Al mismo tiempo, generalmente se generará un error WSAEWOULDBLOCK. No importa. Ejecutar select nuevamente es un tiempo de espera real.

WSADATA wsd;

SOCKET cClient;

int ret;

struct sockaddr_in servidor;

hostent * host=NULL;

if(WSAStartup(MAKEWORD(2,0),&wsd)){return 0;}

cClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if(cClient==INVALID_SOCKET){return 0;}

//establecer tiempo de espera de recepción y envío

int TimeOut=6000 //Establecer tiempo de espera de envío 6; Segundos

if(::setsockopt(cClient,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){

return 0;

}

TimeOut=6000;//Establezca el tiempo de espera de recepción en 6 segundos

if(::setsockopt(cClient,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof (TimeOut ))==SOCKET_ERROR){

return 0;

}

//Establecer conexión sin bloqueo

sin firmar largo ul = 1;

ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul);

if(ret==SOCKET_ERROR)return 0;

/ /Conexión

server.sin_family = AF_INET;

server.sin_port = htons(25);

server.sin_addr .s_addr = inet_addr((LPCSTR )pSmtp );

if(server.sin_addr.s_addr == INADDR_NONE){return 0;}

connect(cClient,(const struct sockaddr *)&server,sizeof(server)

//Seleccione el modelo, es decir, establezca el tiempo de espera

struct timeval timeout;

fd_set r;

FD_ZERO(&r); );

p>

FD_SET(cClient, &r);

timeout.tv_sec = 15; //Tiempo de espera de conexión 15 segundos

timeout.tv_usec =0;

ret = select(0, 0, &r, 0, &timeout);

si (ret <= 0 )

{

::closesocket(cClient );

return 0;

}

//Generalmente, los sockets en modo sin bloqueo son más difíciles de controlar Puede considerar volver a configurarlo en modo de bloqueo según la situación real

unsigned long ul1= 0 ;

ret = ioctlsocket(cClient, FIONBIO, (u.

nsigned long*)&ul1);

if(ret==SOCKET_ERROR){

::closesocket (cClient);

return 0;

}

------------------------------------------ --- ----------------------------------------------- --- ---------------------

Método en LINUX:

En el caso general de bloqueo de sockets, connect() no regresará hasta que llegue el mensaje ACK del cliente para el mensaje SYN. Una forma de hacer que la llamada connect() tenga un tiempo de espera es hacer que el socket no se bloquee y luego usar select() para esperar a que se complete.

[code:1:7901c37cf2]

s = socket(AF_INET, SOCK_STREAM, 0);

//Obtén el indicador de socket a continuación

p>

if ((flags = fcntl(s, F_GETFL, 0)) < 0) {

//Manejo de errores

}

/ /Lo siguiente configura el socket para que no sea bloqueante

if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {

//Manejo de errores

}

if ((retcode = connect(s, (struct sockaddr*)&peer, sizeof(peer)) &&

errno != EINPROGRESS) {

//Debido a que el socket está configurado en NONBLOCK, normalmente la conexión no se establecerá antes de que connect() regrese

//Por lo tanto, devolverá un error EINPROGRESS si regresa

//Cualquier otro error, se requiere manejo de errores

}

if (0 == retcode) { //Si connect() devuelve 0, la conexión se ha establecido

p>

//Restaurar el estado de bloqueo del socket a continuación

if (fcntl(s, F_SETFL, flags) < 0) {

//Manejo de errores

}

//El siguiente es el código que se ejecutará después de que la conexión sea exitosa

exit(0)

}

FD_ZERO( &rdevents);

FD_SET(s, &rdevents); //Agrega el socket anterior al conjunto de lectura

wrevents = rdevents; //Escribe el conjunto

exevents = rdevents; //Recopilación de excepciones

tv.tv_sec = 5; //Establece el tiempo en 5 segundos

tv_tv_usec = 0;

retcode = select(s+1, &rdevents, &wrevents, &exevents, &tv);

if (retcode < 0) { //select devuelve error

//Manejo de errores

}

else if (0 == retcode) { //seleccionar tiempo de espera

//procesamiento del tiempo de espera

}

esle {

//El socket está listo

if (!FD_ISSET(s, &rdevents) && !FD_ISSET(s, &wrevents)) {

/ /connect() falla, realice el manejo de errores

}

if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {

//getsockopt() falló, manejo de errores

}

if (err != 0) {

//connect() falló, manejo de errores

Procesamiento

}

//Aquí se explica que connect() regresa correctamente

//Lo siguiente restaura el estado de bloqueo del socket

if (fcntl(s, F_SETFL, flags) < 0) {

//Manejo de errores

}

//El siguiente es el código que se debe ejecutado después de que la conexión sea exitosa

exit(0)