2009-12-11 26 views
8

Mi función recv se cuelga mientras recibe la respuesta del servidor.Programación de socket C/C++ - ¿la función recv se cuelga?

código del lado del cliente en C/C++:

void sockStuff() { 

int sock, bytes_recieved,bytes_send; 
char send_data[1024], recv_data[4096]; 

struct hostent *host; 
struct sockaddr_in server_addr; 

host = gethostbyname("127.0.0.1"); 

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
    perror("SocketError"); 
    exit(1); 
} 
server_addr.sin_family = AF_INET; 
server_addr.sin_port = htons(50500); 
server_addr.sin_addr = *((struct in_addr *) host->h_addr); 
bzero(&(server_addr.sin_zero), 8); 


if (connect(sock, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) 
    == -1) { 
    perror("ConnectToError"); 
    exit(1); 
} 


    bytes_send = send(sock, a, strlen(a), 0); 
    bytes_send = shutdown(sock, 1); 


bytes_recieved = recv(sock, recv_data, 4096, 0); //Where the program hangs?? 
recv_data[bytes_recieved] = '\0'; 
printf("\nRecieved data = %s ", recv_data); 
cout << endl << endl; 

shutdown(sock,2); 



} 

Mi cliente es lateral/C++ y el servidor C es OpenEdge Progress. Por favor, vea el código y sugiera qué salió mal con esto. ??

+0

Debería usar sizeof (server_addr.sin_zero) en lugar del número mágico 8. O mejor aún, poner a cero toda la estructura y luego establecer los campos que le interesan. –

+0

Hola Neil, ¿puedes por favor elaborar esto más cuando intenté sizeof (server_addr.sin_zero) en lugar del número 8, pero todavía no hay suerte. Thnx. – Vishal

Respuesta

1

recv debe esperar hasta que obtenga respuesta del servidor, ha indicado que la respuesta se está enviando.
Pruebe wireshark o algo así para olfatear la red y ver si la respuesta real está llegando o no.

+0

En realidad, después de que recv() se cuelga, intenté ctrl + alt + del.By haciendo esto, se abre el administrador de tareas pero cierro este administrador de tareas (no eliminé ningún proceso) y de repente me responde una vez. Pero mi programa todavía está congelado . – Vishal

1

Ummm .... ¿Por qué ha apagado la toma ....

 
bytes_send = send(sock, a, strlen(a), 0); 
    bytes_send = shutdown(sock, 1); /*** That I think is the problem! ***/ 


bytes_recieved = recv(sock, recv_data, 4096, 0); 

Y sin embargo, continuó en el código para recibir del mismo socket que estaba apagado ??

Espero que esto te indique la dirección correcta, Saludos cordiales, Tom.

+0

Thnx. Tom por responder. Pero apagado (calcetín, 1); no está cerrando el socket. Solo dice que el envío no está permitido (nada más que enviar). Incluso si elimino esta línea, mi recv() se cuelga. – Vishal

+0

@Vishal: Ok ... http: //www.developerweb.net/forum/showthread.php? T = 2940 - hay una interesante discusión abotu cuando usar shutdown .. El código está en modo sincrónico, podría ser posible que la recepción de datos ya ha sucedido antes del cierre y, por lo tanto, se cuelga. ¿Has pensado en eso ...? Lo siento si no soy de mucha ayuda aquí ... :( – t0mm13b

1

Recv bloqueará hasta que el socket tenga información para leer, siempre y cuando el socket esté en modo de bloqueo, puede cambiar esto con fcntl.

Si se está preguntando por qué está colgado, supongo que cuando apague el tubo de escritura en el zócalo (también, es posible que desee usar el SHUT_WR constante ya que es mejor estilo) el servidor recibe un EOF y asume estás desconectado, aunque ese podría no ser el caso si el servidor está configurado para manejarlo.

Sugeriría buscar en configurar el socket en modo no-bloqueo, luego llamar al select que se bloqueará hasta que el socket sea legible/escribible/o se active un tiempo de espera. Dependiendo de lo que estés haciendo, eso hará la diferencia.

8

Su código se bloqueará en la llamada recv hasta que el servidor envíe cualquier información. Como eso no está sucediendo, tal vez deba preguntarse si su cliente envió la solicitud completa. El servidor probablemente no comenzará a enviar la respuesta hasta que se reciba la solicitud completa.

Si su protocolo cliente/servidor está basado en texto, como HTTP o SMTP, ¿está seguro de que su respuesta ha finalizado correctamente? El servidor puede estar esperando CR + LF ('\ r \ n') en lugar de sólo LF ('\ n') o que espera una línea vacía para terminar la solicitud:

char *request = "GET /index.html HTTP/1.1\r\nHost: www.example.com\r\n\r\n"; 

PS. No declara ni inicializa 'a' en su fragmento de código.

4

Su código se bloqueará en la llamada recv hasta que el servidor envíe cualquier información. Como eso no está sucediendo, tal vez deba preguntarse si su cliente envió la solicitud completa. El servidor probablemente no comenzará a enviar la respuesta hasta que se reciba la solicitud completa.

Si su protocolo cliente/servidor está basado en texto, como HTTP o SMTP, ¿está seguro de que su respuesta ha finalizado correctamente? El servidor puede esperar CR + LF ('\ r \ n') en lugar de solo LF ('\ n') o espera que una línea vacía termine la solicitud:

char * request = "GET/index. html HTTP/1.1 \ r \ nHost: www.example.com \ r \ n \ r \ n "; PD. Usted no declara ni inicializa 'a' en su fragmento de código. "Por notacat

Estaba trabajando en mi copia de la implementación temprana de winsock 1.0 y 1.1 en C++ en win. Mi código funcionó hasta recv () llamar, y luego simplemente quedarme ahí ... sabía sobre el bloqueo \ No bloqueos, pero esa no era la solución que necesitaba. Desde que vi mi solicitud en wireshark o similar, sabía que el servidor estaba recibiendo mi solicitud de fin de cadena en puerto 80, y mi código se congela en la llamada a recv() debido a la falta de comunicación entre mi cliente y el servidor en 'net. Lo que me llevó a creer que no presenté la solicitud adecuada. ¡Bueno, el autor (notaket) estaba en el lugar! . Tan pronto como cambié a su solicitud ("GET /index.html HTTP/1.1 \ r \ nHost: www.example.com \ r \ n \ r \ n"), ¡todo parece funcionar como un hechizo! Gracias !!

Cuestiones relacionadas