柔性数组在网络编程中的应用

bsnry 2012-10-06 02:16:11
有人和我说, 网络编程中应用柔性数组

我就没搞懂,为什么要用它



网络编程中,定义包的时候,分为:head+body

head中有包的类型,body长度, 校验码等信息。

请问:这与柔性数组有什么关系呢?


...全文
164 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaohuh421 2012-10-11
  • 打赏
  • 举报
回复
实在抱歉啊, 我对于网络应用程序的经验实在是不多, 不能帮到你了.
你的方案说所有接收的数据包都放在同一个缓冲区, 那么不管包头数据分开接收还是怎么收, 你就要保证处理当前套接字的包时就要等全部处理完, 当然这样会带来性能问题.

你也可以为每个套接字申请一个数据缓冲区, 这样就不会有问题了,但是又会带来内存资源消耗的问题, 特别是大型服务器程序, 连接数一多起来, 那就悲剧了.

要解决这个问题,估计你得请教在网络服务器编程中比较有经验的前辈们. 比如说参与过大型网络游戏服务器端开发的.

当然12306的前辈就不用问了
bsnry 2012-10-07
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

楼主的这种想法就是错误的.
如果是一个服务器程序, 每接收一个包就是申请一个内存,然后再去释放, 这样就会产生大量内存碎片,最终导致内存分配失败.

在网络程序中, 应该有内存池来负责接收数据, 然后组包/拆包.
为什么要组包/拆包,因为有可能你发送的两个包会被组成一个包发出去, 也可能2.5个包组成一个包发出去. 也就是说,你接收端执行一个recv接收到的可能不是只一个包,也可能不满一……
[/Quote]



大神你还在啊?
bsnry 2012-10-06
  • 打赏
  • 举报
回复
6楼 如何?
bsnry 2012-10-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

楼主的这种想法就是错误的.
如果是一个服务器程序, 每接收一个包就是申请一个内存,然后再去释放, 这样就会产生大量内存碎片,最终导致内存分配失败.

在网络程序中, 应该有内存池来负责接收数据, 然后组包/拆包.
为什么要组包/拆包,因为有可能你发送的两个包会被组成一个包发出去, 也可能2.5个包组成一个包发出去. 也就是说,你接收端执行一个recv接收到的可能不是只一个包,也可能不满一……
[/Quote]

我觉得 如果遇到这种 混烂的问题, 原因是设计出了故障!!

比如 一个线程函数(采用事件选择模型,一个线程可以应付几十个套机字的模型,不知道你熟悉嘛)

,这个函数 即可以接受很短的文字,又可以接受 所谓变长的数据。

你想,如果服务器的这个函数要接受变长,那么就必须 将包头和包身分开来接受, 然后组合一下,再讲包头和包身重新组合,转发或者做其他, 面对多个套接字的时候,必然会出现问题了。

最终组合的数据所存储的缓冲区 是同一个缓冲区,就会乱了。


解决问题的法子:要么用固定大小的包,服务器用固定大小的缓冲区去接受后(每一个包里有头+body),做其他; 要么用两类套接字,

一类来接受 数据较少的包; 一类用来接受变长这种包。

不知道你有怎么想的



xiaohuh421 2012-10-06
  • 打赏
  • 举报
回复
楼主的这种想法就是错误的.
如果是一个服务器程序, 每接收一个包就是申请一个内存,然后再去释放, 这样就会产生大量内存碎片,最终导致内存分配失败.

在网络程序中, 应该有内存池来负责接收数据, 然后组包/拆包.
为什么要组包/拆包,因为有可能你发送的两个包会被组成一个包发出去, 也可能2.5个包组成一个包发出去. 也就是说,你接收端执行一个recv接收到的可能不是只一个包,也可能不满一个包. 哪怕你发送的时候是一个包一个包的发送的.上面那些情况仍然有可能发生,尤其是数据量比较大的情况下.

我想柔性数组很多情况下,不应该用在接收端, 接收端只根据包头信息从接收到的数据中解析出一个包的内容,并处理.

你说的A和B混的问题是不存在的, 因为不管TCP还是UDP,接收函数所对应的套接字都是不同的. 除非你对他们都使用了相同的缓冲区, 并且没有处理好那些数据.

bsnry 2012-10-06
  • 打赏
  • 举报
回复
bsnry 2012-10-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

比如有如数据结构如下
struct MyStruct
{
int x;
int y;
};

然后你的程序中需要发送的数据包括多个这样的结构体数据,但个数又不确定, 那就可 以使用柔性数组了.

struct Package
{
DWORD dwSize; //指定长度
Head head;
MyStruct st[1];//柔……
[/Quote]

我怎么感觉你说的和我想法的不到一块呢

比如:定义一个结构体,这个结构体大小不确定,原因:

这种结构体用于网络传输, 类型多种,如:文字,语音,文件,等等!

暂且不讨论柔性数组, 那么每次发送多少数据给服务器合适呢?

如果有此只发送了四五个字符给服务器(除去包头), 但是我们的结构体大小是固定的,这样的话

会造成浪费!!!!


所以有人建议我用柔性数组,可惜,他没有和我说清楚,如何使用 ,我猜测是这样的意思:

如果发送几个文字,那么就new一定的大小,然后发送, 服务器在接受的时候, 缓冲区则是:

包的头的大小, 从缓冲区中读取body的长度后,才去 new body!!!, 再次接收客户端发送来的数据!!

说白了就是为了避免缓冲区定义过大,或者过小而已!


如果发送文件的时候, 可以每次从客户端取一定大小的数据,然后发送给服务器,服务器也是每次先new 一个head, 从head中读取body的长度后,才去new body!


//////////////////////////////////
以上均是我猜测的


/////////////////////////////////////////////////////

这样的做法会带来一定的风险, 多个客户端发送的时候,tcp传输数据会不会,导致这样的现象出现:

客户端A和客户端B发送数据给服务器, 服务器收到A的head后,就new了一个body,再次接受A的 body,

由于B也在发送, 那么会不会造成 结果接受的是B的head!



这个可不是能用 编号能够解决的, 已经接受了A的head了,打算收A的body,结果收到了B的head或者B的body,

要知道 body是无法区分的,要是能够却分,就不叫body了,叫head 了



xiaohuh421 2012-10-06
  • 打赏
  • 举报
回复
比如有如数据结构如下
struct MyStruct
{
int x;
int y;
};

然后你的程序中需要发送的数据包括多个这样的结构体数据,但个数又不确定, 那就可 以使用柔性数组了.

struct Package
{
DWORD dwSize; //指定长度
Head head;
MyStruct st[1];//柔性数组. C中可以写成0,更好用.
}

申请空间的时候;
比如要发送N个MyStruct
BYTE *pBuf = new BYTE[sizeof(Package)+(N-1)*sizeof(MyStruct)];
Package *pPack = (Package*)pBuf;
pPack->dwSize = .....

pPack->st[N-1]; //可像数组一样访问N个MyStruct.

柔性数据大概就是这样了, 我的理解.

当然, 你说可以使用指针来单独分配MyStruct,是对的
但是使用柔性数组比指针的好处在于, 你 delete pPack就可以释放全部内存,而不需要单独为那个指针调用一次释放内存的操作.
  • 打赏
  • 举报
回复
第一次听到柔性数组,呵呵
内容概要:本文详细介绍了C语言柔性数组的概念、特性及其应用柔性数组是C99标准引入的一种结构体成员,允许最后一个成员为未知大小的数组,从而实现动态内存管理。文章讲解了柔性数组的使用条件(必须位于结构体末尾且前面至少有一个其他成员)、sizeof运算符不包含其内存大小、需通过malloc动态分配内存等核心特点,并通过多个代码示例展示了其定义、初始化、访问和释放过程。同时,对比了柔性数组与指针实现动态数组在内存释放和访问效率上的差异,突出其内存连续性和管理便捷性的优势。最后列举了柔性数组在网络通信协议数据处理等实际场景的典型应用。; 适合人群:具备C语言基础,熟悉结构体、指针和动态内存管理的初级开发者,尤其是从事系统编程或嵌入式开发的技术人员。; 使用场景及目标:①需要处理变长数据结构(如网络数据包、消息帧)时设计高效内存模型;②优化内存使用,避免冗余分配或多次内存操作带来的性能损耗;③深入理解C语言底层内存布局与访问机制。; 阅读建议:学习时应结合代码示例动手实践,重点关注动态内存分配方式、内存连续性带来的效率提升以及与传统指针方案的对比,理解其在真实项目的适用边界与最佳实践。

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧