套接字编程C / C ++ - recv函数挂起?

时间:2009-12-11 12:11:10

标签: c sockets

我的recv函数在从服务器获得响应时挂起。

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



}

我的客户端是C / C ++,服务器端是OpenEdge Progress。 请查看代码并提出问题,并说明这有什么问题。??

6 个答案:

答案 0 :(得分:8)

您的代码将在recv调用中阻塞,直到服务器发回任何数据。既然没有发生这种情况,也许您应该问问自己您的客户是否发送了完整的请求。在收到完整请求之前,服务器可能不会开始发送响应。

如果您的客户端/服务器协议是基于文本的,如HTTP或SMTP,您确定您的响应是否正确终止?服务器可能期望CR + LF('\ r \ n')而不仅仅是LF('\ n'),或者它期望空行终止请求:

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

PS。您不会在代码段中声明或初始化“a”。

答案 1 :(得分:4)

您的代码将在recv调用中阻塞,直到服务器发回任何数据。既然没有发生这种情况,也许您应该问问自己您的客户是否发送了完整的请求。在收到完整请求之前,服务器可能不会开始发送响应。

如果您的客户端/服务器协议是基于文本的,如HTTP或SMTP,您确定您的响应是否正确终止?服务器可能期望CR + LF('\ r \ n')而不仅仅是LF('\ n'),或者它期望空行终止请求:

char * request =“GET /index.html HTTP / 1.1 \ r \ nHost:www.example.com \ r \ n \ r \ n”; PS。你没有在你的代码片段中声明或初始化'a'。“by notacat

我正在使用c ++上的早期winsock 1.0和1.1实现我的副本。 我的代码一直工作到recv()调用,然后挂在那里......我知道阻塞\非阻塞套接字,但这不是我需要的解决方案。由于我在wireshark或类似的地方看到了我的请求,我知道服务器在端口80上接收到我的字符串请求结束,并且由于我的客户端和服务器之间的网络不通信,我的代码冻结了recv()调用。这让我相信我没有提交适当的要求。那么,作者(notaket)就在现场!一旦我改变了他的要求(“GET /index.html HTTP / 1.1 \ r \ nHost:www.example.com \ r \ n \ r \ n”),所有人似乎都像魅力一样!谢谢!

答案 2 :(得分:2)

recv应该挂起,直到你收到服务器的回复,你是否说过要发送回复 尝试使用wireshark或类似的东西来嗅探网络并查看实际响应是否即将到来。

答案 3 :(得分:1)

嗯....你为什么关闭套接字......

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

然而你继续在代码中接收来自关闭的同一个套接字?

希望这能暗示你朝着正确的方向前进, 最好的祝福, 汤姆。

答案 4 :(得分:1)

只要套接字处于阻塞模式,Recv就会阻塞,直到套接字有信息可读,你可以用fcntl更改它。

如果你想知道为什么它会挂起,我的猜测是当你关闭套接字上的写管道时(你也可能希望使用常量SHUT_WR,因为它的样式更好),服务器会收到一个EOF并假设你'断开连接,但如果服务器设置为处理它可能不是这种情况。

我建议将套接字设置为非阻塞模式,然后调用select,它将阻塞,直到套接字可读/可写/或触发超时。根据你正在做的事情,这将有所作为。

答案 5 :(得分:1)

尝试使用非阻止模式。如果没有数据可供读取,则recv将返回,因此处理这种情况(在while循环中或使用select。由你决定)

有关recv的更多信息,假设您使用的是POSIX兼容系统)请阅读此内容 http://www.opengroup.org/onlinepubs/009695399/functions/recv.html