为什么我的recv呼叫阻止?

时间:2015-08-20 23:50:01

标签: c tcp

我有一个简单的Web服务,可以通过HTTP访问。我有一个使用此服务的c程序。由于我无法理解的原因,我的recv电话会阻塞近5秒钟。响应的大小小于600字节,API调用的时间少于100毫秒(从浏览器调用时)。

可能导致此行为的原因是什么?我尝试过使用TCP_NODELAY选项,这似乎没什么区别。 send命令(大小相似,并且在recv之前发生)相对较快。

编辑:代码,根据要求 - 整个函数很大,但这是有问题的代码:

connect(tcpSocket, (struct sockaddr *) &serveraddr, sizeof(serveraddr));

char* args = cJSON_PrintUnformatted(root);
sprintf(request_string, "GET %s?json=%s HTTP/1.1\r\nHost: %s\r\n\r\n\r\n", API_PAGE, curl_easy_escape(NULL, args, strlen(args)), API_HOST);
send(tcpSocket, request_string, strlen(request_string), 0);
recv(tcpSocket, request_string, 4095,0);

EDIT2:tcpdump输出

20:03:03.976311 IP localhost.48732 > localhost.http: Flags [S], seq 3254094788, win 43690, options [mss 65495,sackOK,TS val 83001890 ecr 0,nop,wscale 7], length 0
20:03:03.976324 IP localhost.http > localhost.48732: Flags [S.], seq 3772034334, ack 3254094789, win 43690, options [mss 65495,sackOK,TS val 83001890 ecr 83001890,nop,wscale 7], length 0
20:03:03.976335 IP localhost.48732 > localhost.http: Flags [.], ack 1, win 342, options [nop,nop,TS val 83001890 ecr 83001890], length 0
20:03:03.976367 IP localhost.48732 > localhost.http: Flags [P.], seq 1:380, ack 1, win 342, options [nop,nop,TS val 83001890 ecr 83001890], length 379
20:03:03.976382 IP localhost.http > localhost.48732: Flags [.], ack 380, win 350, options [nop,nop,TS val 83001890 ecr 83001890], length 0
20:03:09.055255 IP localhost.http > localhost.48732: Flags [P.], seq 1:605, ack 380, win 350, options [nop,nop,TS val 83003159 ecr 83001890], length 604
20:03:09.055293 IP localhost.48732 > localhost.http: Flags [.], ack 605, win 351, options [nop,nop,TS val 83003159 ecr 83003159], length 0
20:03:09.055310 IP localhost.48732 > localhost.http: Flags [F.], seq 380, ack 605, win 351, options [nop,nop,TS val 83003159 ecr 83003159], length 0
20:03:09.055314 IP localhost.http > localhost.48732: Flags [F.], seq 605, ack 380, win 350, options [nop,nop,TS val 83003159 ecr 83003159], length 0
20:03:09.055320 IP localhost.48732 > localhost.http: Flags [.], ack 606, win 351, options [nop,nop,TS val 83003159 ecr 83003159], length 0
20:03:09.055320 IP localhost.http > localhost.48732: Flags [.], ack 381, win 350, options [nop,nop,TS val 83003159 ecr 83003159], length 0

2 个答案:

答案 0 :(得分:0)

让我们回顾一下tcpdump:

首先,TCP连接建立:

20:03:03.976311 IP localhost.48732 > localhost.http: Flags [S], seq 3254094788, win 43690, options [mss 65495,sackOK,TS val 83001890 ecr 0,nop,wscale 7], length 0
20:03:03.976324 IP localhost.http > localhost.48732: Flags [S.], seq 3772034334, ack 3254094789, win 43690, options [mss 65495,sackOK,TS val 83001890 ecr 83001890,nop,wscale 7], length 0
20:03:03.976335 IP localhost.48732 > localhost.http: Flags [.], ack 1, win 342, options [nop,nop,TS val 83001890 ecr 83001890], length 0

接下来,从客户端发送到服务器的数据和收到的ACK:

20:03:03.976367 IP localhost.48732 > localhost.http: Flags [P.], seq 1:380, ack 1, win 342, options [nop,nop,TS val 83001890 ecr 83001890], length 379
20:03:03.976382 IP localhost.http > localhost.48732: Flags [.], ack 380, win 350, options [nop,nop,TS val 83001890 ecr 83001890], length 0

并且,5秒后!来自服务器的回答:

20:03:09.055255 IP localhost.http > localhost.48732: Flags [P.], seq 1:605, ack 380, win 350, options [nop,nop,TS val 83003159 ecr 83001890], length 604
20:03:09.055293 IP localhost.48732 > localhost.http: Flags [.], ack 605, win 351, options [nop,nop,TS val 83003159 ecr 83003159], length 0

最后,关闭连接:

20:03:09.055310 IP localhost.48732 > localhost.http: Flags [F.], seq 380, ack 605, win 351, options [nop,nop,TS val 83003159 ecr 83003159], length 0
20:03:09.055314 IP localhost.http > localhost.48732: Flags [F.], seq 605, ack 380, win 350, options [nop,nop,TS val 83003159 ecr 83003159], length 0
20:03:09.055320 IP localhost.48732 > localhost.http: Flags [.], ack 606, win 351, options [nop,nop,TS val 83003159 ecr 83003159], length 0
20:03:09.055320 IP localhost.http > localhost.48732: Flags [.], ack 381, win 350, options [nop,nop,TS val 83003159 ecr 83003159], length 0

在conclusión中,服务器导致延迟。

答案 1 :(得分:0)

最后,这个问题不是由于客户端上发生的任何事情,而是PHP服务器停止响应的问题。解决方案是在终止服务器上的连接之前立即刷新响应。

目前尚不清楚为什么在从程序客户端而不是浏览器访问API时,此问题才会出现。浏览器可能会使用标头来确保数据立即传输,或者将参数传递给客户端上的套接字连接,以确保它立即处理返回的数据,即使连接未被视为完整。