【问题标题】:Two times send and recv are not working C两次发送和接收都不起作用 C
【发布时间】:2017-01-10 21:04:04
【问题描述】:

我遇到了一个我无法真正解决的问题,所以我重新启动了。 我遇到了数据封装的问题,或者更具体的没有封装的问题。所以在我发现封装有用之后,我开始重写代码。

现在我遇到了另一个问题。不知何故,我的 send 和 recv 调用并没有像我希望的那样工作。

这是我发送的部分:

char to_send[] = "hello. I am the Data.";

  // get size of data
  int len = strlen(to_send);
  char slen[len];
  sprintf(slen,"%d",len);
  printf("%s\n",slen);
  // send size of data
  if(send(comm_fd,slen,len,0)<0){perror("Error on send"); exit(1);}

  // send data
  if(send(comm_fd,to_send,len,0)<0){perror("Error on send"); exit(1);}

这里是我recv的部分:

// getting size of bytes to recv
  char buf[1000];
  bzero(buf,1000);

  int rec = recv(comm_fd, buf, 100,0);
  printf("rec\n: %i",rec);
  printf("buf\n: %s\n", buf);

  int buffsize;
  buffsize = atoi(buf);
  bzero(buf,1000);
  printf("buffsize: %i\n",buffsize);

  // recv the bytes
  bzero(buf,1000);
  rec = recv(comm_fd, buf, buffsize,0);
  printf("rec\n: %i",rec);
  printf("%s",buf);

所以我现在的问题是:我可以接收下一个数据的大小并打印它。但是数据本身没有显示出来。

有人可以帮助我吗?我认为我做错了主要事情(我是 C 和网络编程的新手)

提前致谢

【问题讨论】:

  • slen 的大小不是len

标签: c sockets networking send recv


【解决方案1】:

第一次send 电话有两件事:

if(send(comm_fd,slen,len,0)<0){perror("Error on send"); exit(1);}

这里你发送len的字节数,但lento_send的长度而不是slen的长度。您很可能会从slen 的初始化部分之外发送数据,这会导致未定义的行为

第二个问题是您将to_send 的长度作为可变长度字符串发送,因此接收者实际上并不知道要接收多少。在您的情况下,您实际上可以(并且可能确实)在单个 recv 调用中接收长度 字符串。至少如果您使用的是 TCP(streaming)套接字。

这两个问题都可以通过将slen 设为一个固定大小的数组来解决,大到足以容纳你能想到的最大数字(通常十位数就足够了),然后使用@发送这个固定长度的数组987654331@.

大概是这样的:

// Ten digits, plus string terminator
char slen[10 + 1];

// Prefix length with zeroes, and don't overflow the buffer
snprintf(slen, sizeof(slen), "%010d", strlen(to_send));

// Send the whole array, including terminator
send(comm_fd, slen, sizeof slen, 0);

那么在接收端,你可以这样做

// Ten digits, plus string terminator
char slen[10 + 1];

// Receive the whole string, including terminator
recv(comm_fd, slen, sizeof(slen), 0);

// Convert to a number
size_t len = strtoul(slen, NULL, 10);

// Now receive `len` bytes

请注意,我没有错误检查,你应该有。

【讨论】:

  • 成功了!多谢!我看到我的错误广告将阅读有关您使用的功能的信息。谢谢
  • 另外,在现代程序中使用memset 而不是bzero(POSIX 已弃用)
  • snprintf(slen, sizeof(slen), "%010d", strlen(to_send)); 有问题。典型的 int(这是 %d 所期望的类型)最多需要 11 + 1 char,而不是 10。例如-2147483648strlen() 返回类型 size_t 可能与 %d 不匹配。也许你想要%zu,那么 10 可能就可以了。使用snprintf() 来防止溢出并且不检查snprintf() 的返回值的代码正在用一个问题换另一个问题。最好检查它的返回值。
  • size_t len = strtoul(slen, NULL, 10); 将受益于先前的slen[sizeof slen -1] = 0;。推荐这种防御性编码,因为来自另一个进程的输入不应该被完全信任。
猜你喜欢
  • 2015-10-11
  • 1970-01-01
  • 2013-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 2014-11-25
相关资源
最近更新 更多