c套接字发送和接收int而不是char缓冲区

标签 c sockets

1:服务器将文件大小复制到缓冲区中并发送:

  snprintf(t_buf, 255, "%" PRIu32, fsize);
  if(send(f_sockd, t_buf, sizeof(t_buf), 0) < 0){
    perror("error on sending file size\n");
    onexit(f_sockd, m_sockd, 0, 2);
  }

2:客户端接收到文件大小,放入fsize中:

  if(recv(f_sockd, t_buf, sizeof(t_buf), 0) < 0){
    perror("error on receiving file size");
    onexit(f_sockd, 0 ,0 ,1);
  }
  fsize = atoi(t_buf);

----------------- 上面的代码使我的程序完美运行!

如果我编写此代码而不是上一个代码,则会出现问题:
1:服务器发送fsize:

  if(send(f_sockd, &fsize, sizeof(fsize), 0) < 0){
    perror("error on sending file size\n");
    onexit(f_sockd, m_sockd, 0, 2);
  }

2:客户端收到fsize:

  if(recv(f_sockd, &fsize, sizeof(fsize), 0) < 0){
    perror("error on receiving file size");
    onexit(f_sockd, 0, 0, 1);
  }

其中uint32_t fsize;char t_buf[256];
问题是,第一种方法可以正常工作,但第二种方法客户端不会收到所有文件,而只会收到其中的一部分。这段代码有什么问题?
谢谢!

最佳答案

recv(2)不一定填满完整的输出缓冲区 - 它可能返回更少的字节,具体取决于可用数据量:

The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested.

返回值(当 > 0 时)将是接收到的字节数,因此如果您想确保接收到所有内容,可以循环调用它。

或者,您可以传递 MSG_WAITALL 标志:

This flag requests that the operation block until the full request is satisfied. However, the call may still return less data than requested if a signal is caught, an error or disconnect occurs, or the next data to be received is of a different type than that returned.

因此,就您的情况而言,您可以执行以下操作:

ssize_t bytes = recv(f_sockd, &fsize, sizeof(fsize), MSG_WAITALL);

if(bytes == sizeof(fsize))
{
    /* received everything */
}
else
{
    /* something went wrong */
}

关于c套接字发送和接收int而不是char缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12175887/

相关文章:

c++ - 一组根据操作数类型而不同名称的函数可以在C语言中称为理论上的静态多态吗?

c - 单击鼠标时选择基元不起作用

我们可以在函数返回数据类型为 void 的例程中调用函数吗?

c - 优先级在 C 表达式求值中的作用

python - 如何获取 Udp 缓冲区大小超过丢失的数据包

c - 声明具有不同类型的结构体属性

java - 文件传输后保留文件名

node.js - 在客户端之间发送消息socket.io

java - Java NIO 的选择器如何在底层检查可用事件?

java - 使用带有套接字的 Javas 对象流的性能问题