繁体   English   中英

为什么我的recv调用被阻止?

[英]why does my recv call block?

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

是什么导致这种行为? 我尝试使用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

让我们回顾一下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

在总结中,服务器造成了延迟。

最后,这个问题不是由于客户端上发生了什么,而是由于PHP服务器停止了响应所引起的。 解决方案是立即终止响应,然后再终止服务器上的连接。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM