网络通信中,数据包是定长好还是不定长好?

时间:2022-08-04 04:09:30
我现在的程序,除了三种情况,数据量比较大,其他的都是一些小包。
我以前都是用定长数据包做的。
但是现在好像感觉不太适用。
因为大多数的情况数据量比较小,每次都发那么大的数据,好像浪费资源了。
所以考虑用不定长方式,
这样问题就来了,接收端怎么知道发过来的数据包有多长,
如果接收长度添的长了,那么可能收了两个数据包,
如果短了,可能收到的数据包不完整。
怎么做好呢?
是不是一定要事先发一个包头,来通知对方,然后对方再根据包头中的长度来recv数据?
有没有更好的方法?

18 个解决方案

#1


看需求吧

#2


如果需要是变长的,是否只能先发一个包头,告诉对方我要发的数据量,然后对方根据包头来接收数据?

#3


来几个高手给个意见啊

#4


常见4K, 比较好, 正好是磁盘一个CLUSTER

#5


对比较小的数据采用不定长比较好,数据分为数据头和数据两个部分。
数据头中含有数据的长度,在接受的时候分两次接受就可以了。
根据数据头中的长度决定接受后面的多长的数据。

#6


不定长的好 可以节省空间 包分包头和包体  包头固定,其中一个字段表示包体的长度。这样就可以把一个包拆分开来。

/*----------------------包头---------------------*/
typedef struct _PACKAGE_HEAD
{
BYTE m_Version;
WORD m_Command;
WORD m_nDataLen;
}PACKAGE_HEAD;

#7


同意楼上的,使用不定长的,"包头(...+包长)+内容(不定长)",另外,如果有一个包很长的话可以在发送的时候分开,按照同一个协议多发几次哦!

#8


应用层的网络协议一般都不定长的啦
三种方法:
一、用UDP,UDP协议是分包发送的,其中已有长度字段;
二、自定义包头,包头中有长度字段;
三、自定义一个结束符。这种法子需要把消息内容中含结束符的部分用转义符替换,实现比较困难。

#9


UP

#10


封装包,根据包头来分析该包的数据长度

#11


如果各种包长度、内容差别很大,当然用不定长的好,不用把包头和包体分开发,一起是一个包,像前面说的,包头+包体,包头定长,其中内容指明包体的长度,包体就可以是变长的了。

#12


我也选不定长的

#13


如果说包头和包体不分开,一次发送。
那么我接收的时候长度怎么填呢?

#14


联通移动短消息网关协议上是(包长度(DWORD)+包头(定长)+包体(变长))
小灵通网关协议(包头(包头+包体长度)(定长)+包体(变长))

#15


定长实现容易写,不定长,效率高些

#16


4k不一定是一个簇的大小,必须看用户机器上的实际情况,我的就是512Byte/簇

#17


如果说包头和包体不分开,一次发送。
那么我接收的时候长度怎么填呢?
如果先发包头,再发包体,是否太累赘?

#18


包长度在发送的时候填呀,接收干吗要填?接收的时候先按固定长度收下包头,再根据包头里的长度接收包体。另外,包头和包体可以一起发送,怎么会累赘呢?

struct MSGHDR {
    DWORD cbMsgSize;
    // ... other information ...
};

struct MSG1 {
    MSGHDR hdr;
    // ... body1 information ...
};

struct MSG2 {
    MSGHDR hdr;
    // ... body2 information ...
};

#1


看需求吧

#2


如果需要是变长的,是否只能先发一个包头,告诉对方我要发的数据量,然后对方根据包头来接收数据?

#3


来几个高手给个意见啊

#4


常见4K, 比较好, 正好是磁盘一个CLUSTER

#5


对比较小的数据采用不定长比较好,数据分为数据头和数据两个部分。
数据头中含有数据的长度,在接受的时候分两次接受就可以了。
根据数据头中的长度决定接受后面的多长的数据。

#6


不定长的好 可以节省空间 包分包头和包体  包头固定,其中一个字段表示包体的长度。这样就可以把一个包拆分开来。

/*----------------------包头---------------------*/
typedef struct _PACKAGE_HEAD
{
BYTE m_Version;
WORD m_Command;
WORD m_nDataLen;
}PACKAGE_HEAD;

#7


同意楼上的,使用不定长的,"包头(...+包长)+内容(不定长)",另外,如果有一个包很长的话可以在发送的时候分开,按照同一个协议多发几次哦!

#8


应用层的网络协议一般都不定长的啦
三种方法:
一、用UDP,UDP协议是分包发送的,其中已有长度字段;
二、自定义包头,包头中有长度字段;
三、自定义一个结束符。这种法子需要把消息内容中含结束符的部分用转义符替换,实现比较困难。

#9


UP

#10


封装包,根据包头来分析该包的数据长度

#11


如果各种包长度、内容差别很大,当然用不定长的好,不用把包头和包体分开发,一起是一个包,像前面说的,包头+包体,包头定长,其中内容指明包体的长度,包体就可以是变长的了。

#12


我也选不定长的

#13


如果说包头和包体不分开,一次发送。
那么我接收的时候长度怎么填呢?

#14


联通移动短消息网关协议上是(包长度(DWORD)+包头(定长)+包体(变长))
小灵通网关协议(包头(包头+包体长度)(定长)+包体(变长))

#15


定长实现容易写,不定长,效率高些

#16


4k不一定是一个簇的大小,必须看用户机器上的实际情况,我的就是512Byte/簇

#17


如果说包头和包体不分开,一次发送。
那么我接收的时候长度怎么填呢?
如果先发包头,再发包体,是否太累赘?

#18


包长度在发送的时候填呀,接收干吗要填?接收的时候先按固定长度收下包头,再根据包头里的长度接收包体。另外,包头和包体可以一起发送,怎么会累赘呢?

struct MSGHDR {
    DWORD cbMsgSize;
    // ... other information ...
};

struct MSG1 {
    MSGHDR hdr;
    // ... body1 information ...
};

struct MSG2 {
    MSGHDR hdr;
    // ... body2 information ...
};