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); p>
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 p>
}
if ((retcode = connect(s, (struct sockaddr*)&peer, sizeof(peer)) &&
errno != EINPROGRESS) { p>
//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)
} p>
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)