套接字数据长度问题

trr*_*rrm 2 c sockets linux network-programming

我有几个与以下代码相关的问题:

char buffer[256];
memset(buffer,0,256);

read(socket_fd,buffer,255);
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 为什么我读255而不是256?
  2. 假设我想从客户端向服务器发送"酷"字样.我应该在"客户端"中写入多少字节,以及"在服务器中"应该读取多少字节?

我真的很困惑.

sle*_*ica 8

你已经有了很好的答案,但我认为我们应该解释一个概念.

当您通过流发送数据时(即,从一端写入多个字节的东西,并且在另一端可以以相同的顺序读取这些字节),您几乎总是想知道何时停止读取.如果您发送多个内容,则必须执行此操作:第一条消息何时停止,第二条消息何时开始?在流中,事情变得混乱.

那么,我们如何划分消息呢?有三种简单的方法(当然还有许多其他不那么简单的方法):

1固定长度的消息:如果您事先知道每条消息都是10字节长,那么您就没有问题.您只需读取10个字节,第11个字节将成为另一个消息的一部分.这非常简单,但也非常严格.

2分隔字符或字符串:如果要发送人类可读的文本,则可以使用与分隔字符串相同的方式分隔邮件.char*:在末尾添加0字符.这样,当您读取0时,您知道消息已结束,并且流中的任何剩余数据都属于另一条消息.

这对于ascii文本是可以的,但是当涉及到任意数据时,它也有点僵硬:你的消息不能包含一个字符或一系列字符(或者你的程序会对消息的结束感到困惑) .

3消息头:这是任意长度,任意内容消息的最佳方法.在发送任何实际的消息数据之前,发送一个固定长度的头(或使用技术nr 2来标记头的末尾),指定有关您的消息的元数据.例如,它的长度.

假设你想发送消息'酷',就像你说的那样.好吧,首先发送一个字节(或一个2字节的短整数,或一个4字节的整数,或其他什么),包含消息的长度'4',并在另一端接收它.您知道在任何消息到达之前,您必须读取1个字节(或2o,或4或其他),因此将其存储在某处,然后读取剩余的指定字节.

很简单的例子:

struct mheader {
    int length;
};

(...)
struct mheader in_h;
read(fd, &in_h, sizeof(struct mheader);

if (in_h.length > 0)
    read(fd, buffer, in_h.length)
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.祝好运!