【问题标题】:Recv hangs even though I followed all conventions?即使我遵循所有约定,Recv 也会挂起?
【发布时间】:2021-05-02 22:41:57
【问题描述】:

我正在尝试创建一个小程序,该程序通过标准输入接收 http 请求并将其发送到服务器。 这是我正在使用的代码:

int portno =        3000;
char *message = buf;
char response[4096];
int byte_count;
fsize = strlen(message);
int sockfd;
/* fill in the parameters */
printf("Request:\n%s\n",message);

/* create the socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error("ERROR opening socket");
int sz = (1024 * 1024);
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof(sz)) == -1) {
    perror("setsockopt");
    exit(1);
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(portno);
saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (connect(sockfd, &saddr, sizeof(saddr)) == -1) {
    perror("connect");
}
send(sockfd, message, fsize, MSG_NOSIGNAL);
printf("written");
byte_count = recv(sockfd,response,sizeof(response)-1,0); // <-- -1 to leave room for a null terminator
response[byte_count] = 0; // <-- add the null terminator
printf("recv()'d %d bytes of data in buf\n",byte_count);
printf("%s",response);
close(sockfd);

buf 等于这个

GET /alias%2Findex.html HTTP/1.0\r\n
\r\n
\r\n
\r\n

我通过其他堆栈溢出帖子进行了一些研究,他们指出当系统等待响应时,recv 通常会挂起。我不知道是什么原因造成的。

【问题讨论】:

  • 缓冲区是否包含文字 \r\n,或者是那些 CR 和 LF 字符?
  • 那些是 CR 和 LF 字符。
  • 当事情不工作时,总是检查你的返回值。您目前不知道send 是否成功。并检查您的 recv 返回值。在写信给response[-1] 时,你会很幸运遇到段错误。

标签: c sockets gcc recv


【解决方案1】:

这是您的程序,只是稍作修改。它对我有用。 您确定在 localhost 端口 3000 上运行的任何服务器都能正常响应吗?顺便说一句,我必须将我的系统的端口更改为 8080。

#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

char buf[1 << 16] = "GET /file.txt HTTP/1.0\r\n"
                    "\r\n"
                    "\r\n";

int main() {
  int portno = 8080;
  char *message = buf;
  int byte_count;
  int fsize = strlen(message);
  int sockfd;
  /* fill in the parameters */
  printf("Request:\n%s\n", message);

  /* create the socket */
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0)
    perror("ERROR opening socket");
  int sz = (1024 * 1024);
  if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof(sz)) == -1) {
    perror("setsockopt");
    exit(1);
  }
  struct sockaddr_in saddr;
  saddr.sin_family = AF_INET;
  saddr.sin_port = htons(portno);
  saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
    perror("connect");
  }
  send(sockfd, message, fsize, MSG_NOSIGNAL);
  printf("written");
  while ((byte_count = recv(sockfd, buf, sizeof(buf) - 1, 0)) >
         0) {            // <-- -1 to leave room for a null terminator
    buf[byte_count] = 0; // <-- add the null terminator
    printf("recv()'d %d bytes of data in buf\n", byte_count);
    printf("%s", buf);
  }
  close(sockfd);

  return 0;
}

【讨论】:

  • 我想我也找到了问题所在。我正在尝试将此代码集成到服务器本身,发生的情况是在服务器初始化之前,运行此代码。我怎样才能创建套接字连接?
  • 我不明白你为什么要在服务器代码中运行这种代码。但是您需要在主事件循环中使用异步 IO,使用服务器使用的任何内容,例如 poll 或 select。或者您需要在单独的线程中运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 2011-06-03
  • 2013-08-13
相关资源
最近更新 更多