2012-11-08 33 views
0

我在QT中进行套接字编程,我必须设计一个通过TCP/IP传输数据的协议。通过套接字修改数据包大小

现在我的协议设计很简单。它以一种方式发送命令,每写入一次,写入套接字的数据的第一个字节就是命令。因此,无论何时使用socket-> write(“CDATA”)写入第一个字节,此时的“C”将意味着服务器执行某些操作的命令。

我只想知道一件事,即写入是否会分解为服务器上的多次读取?我知道服务器上会有一个用于读取的缓冲区大小。但是,当写入处于服务器的缓冲区限制内时,客户机上的socket-> write()是否可以在服务器上的多次读取中接收?

要清除此问题,我将给出一个示例假设服务器上的套接字的缓冲区读取大小为4096字节。客户端将套接字写入(“CDATA”)到服务器。现在有没有可能的服务器会收到多于一个读取?因为我在服务器上有一个while循环:

while{ 
char str[] = socket->read(); 
// What is the coomand in the first byte 
if(str[0] == "C"){ 
    // Do something 
} 
} 

如果由客户端发送的数据在一个以上的读取(即使客户端发送它在一个写)收到我的协议设计将失败。

+3

由于您对大写单词的使用不当,我现在试图解码您的消息可能包含的任何帮助。不要担心人工登录名是否正确 – Wug

回答

1

现在有没有可能,服务器将收到多于一个读取?

是的,TCP/IP可以以任何喜欢的方式对消息进行分段。 TCP是一个有状态的流协议:你保证你放在一端的字节会以相同的顺序从另一端出来。 IP是无连接和基于数据报的。由于承载基于IP的TCP的性质,可能会出现数据包在传输中被拆分,合并或处理的情况。

您应该找到一种方法来清理您的程序,以避免错综复杂的网络通信。您可以:

  • 使用数据报协议(如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] 
    

很可能您可以使用库方法来执行此行为,因为您只需要很少的代码。

+0

例如:HTTP是换行符分隔的。SFTP是一种数据报协议。 FTP,我认为,使用一个标题。 Minecraft使用标题。 SSH,telnet和其他字符shell协议基本上由每个字符分隔。 – Wug

+0

“将传入数据的大小作为附加在前面的标题”这正是这里的问题先生。假设我包含4个字节的头部和4096个字节的数据,但数据在服务器上以2个字节和4098个字节接收。在这种情况下我该怎么办? OR将以4字节和4096字节的连续性接收数据。 – user1066991

+0

您可以使用'read'读取指定大小的数据。我无法找到任何支持使用'socket-> read()'的文档,我找到的所有文档都带有参数。如果你有一个包装类或其他东西,发布它。无论如何,您可以使用'QByteArray QTcpSocket :: read(qint64 maxlen)'从流中读取指定数量的字节。 – Wug