我在QT中进行套接字编程,我必须设计一个通过TCP / IP传输数据的协议。
现在我的协议设计很简单。它以一种方式发送命令,即每次写入时写入套接字的数据的第一个字节将是命令。因此,每当我使用socket-> write(“CDATA”)写入套接字时,第一个字节,在这种情况下,“C”将表示服务器执行某些操作的命令。
我只想知道一件事,即写入是否会被分解为服务器上的多次读取?我知道服务器上会有一个缓冲区大小用于读取。但是当写入服务器的缓冲区限制内时,可以在服务器上的多次读取中接收客户端上的socket-> write()吗?
要清除这个问题,我将给出一个例子让我们说服务器上套接字的缓冲区读取大小是4096字节。客户端将socket-> write(“CDATA”)写入服务器。现在有没有可能服务器会在多个读取中收到这个?因为我在服务器上有一个while循环:
while{
char str[] = socket->read();
// What is the coomand in the first byte
if(str[0] == "C"){
// Do something
}
}
如果客户端发送的数据是多次读取的(即使客户端通过一次写入发送),我的协议设计也会失败。
答案 0 :(得分:1)
现在有没有可能服务器会在多次读取中收到它?
是的,TCP / IP可以按照自己喜欢的方式对消息进行分段。 TCP是一种有状态流协议:保证您在一端输入的字节将以相同的顺序出现在另一端。 IP是无连接和基于数据报的。由于承载TCP over IP的性质,可能会出现数据包在传输过程中被拆分,合并或以其他方式处理的情况。
您应该找到一种方法来清理程序,使其符合网络通信的复杂性。你可以:
使用像UDP这样的数据报协议(你失去了按照发送顺序获取数据的保证,并且丢弃的数据包也成为可能。今天的网络非常强大;这通常不是问题)。
[DATAGRAM (size specified in datagram header)]
始终从网络中读取固定大小的块
[DATA - block of data of some fixed size]
将传入数据的大小包含在前面附加的标题
中[LENGTH - 4 byte integer][DATA - block of data of size LENGTH]
使用某种分隔符来指示数据结束并继续阅读直到你得到它
[DATA - indeterminately sized data][DELIMITER - end-of-data control sequence]
您可以使用库方法来执行此操作,因为您只需要很少的代码。