c - 为什么我的recv调用会阻塞?

标签 c tcp

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

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

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

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

编辑2: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

总而言之,服务器导致了延迟。

关于c - 为什么我的recv调用会阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32130256/

相关文章:

tcp - 访问另一台设备的 Windows 服务

Python套接字发送在多次调用recv后不起作用

c - 设置 TCP_QUICKACK 和 TCP_NODELAY

c - g_string_truncate () 上的段错误?

c - 有没有办法在 C 中引用你所在的函数?

windows-10 - Paho MQTT 在编译期间抛出 undefined reference 错误

http - std::io::TcpStream::read_as_string 返回空字符串

Qt 通过 TCP 发送文件

c - 如何获取函数的 RAM 和 CPU 使用率?

无法在 Adafruit FT232H 上使用 gpiod_line_request_output() 访问 gpio 线