龙空技术网

谨慎!socket编程中,很多程序员都会踩的坑

我不是你的狗 3656

前言:

当前看官们对“socket编程难吗”可能比较关注,我们都想要了解一些“socket编程难吗”的相关文章。那么小编在网络上搜集了一些对于“socket编程难吗””的相关文章,希望你们能喜欢,咱们一起来了解一下吧!

小袁,刚毕业参加工作。在公司负责的模块涉及tcp socket编程。大致业务逻辑是,发送端会发送不同类型的结构体(设置了packed属性,这样就可以直接在char buffer之间拷贝),结构体第一个字节用来标志结构体类型。然后接收端不断接收发送端发过来的数据,收到后根据第一个字节得到结构体类型,这样就可以直接将收到的buffer拷贝到一个对应类型的结构体变量。

几天后,测试组陆续反馈,发送端明明发了100帧结构体,但接收端打印的log只显示收到了99帧数据。

我们知道,APP开发工程师调用send函数发送一条消息,send函数的本质只是把数据放到内核的某个缓冲区。然后运行在内核的网络协议栈,会不断的处理缓冲区里面的数据,并通过网卡驱动程序将数据写进网卡芯片,最终网卡将数据发送出去。理理想情况下,发送端发送一次,接收端接收一次,这样没有任何问题。但事实不尽如人意,比如,在网络情况不好的时候,发送端的数据全部会堆积在内核缓冲区,当网络变好的情况下,一股脑的发送出去。这个时候,接收端会一下子收到很多帧结构体。

下面我们通过在发送端连续发送消息,来模拟网络不好,消息堆积的场景。代码及结果如下俩图:

直观地看出问题来了吗?这里 发送端实际发送了俩次数据,但接收端一次就全部读取接收完了。而且小袁把它当成了一帧数据处理了。

以上只是问题一。其次是,小袁每次都读取1024个字节,并把他当成一帧结构体。但实际上发送端发送的不同类型的结构体size都不一样,这样很可能就会出现读取一次数据,最后面会把一帧结构体的一部分数据读出。下次再去读,就会读到残缺的结构体了。如下图所示:

这个问题让我想到了我之前在某世界500强公司的一个同事。他在安卓APP读取串口数据,每次读到数据后,他不管三七二十一就把读到的数据当成是一帧数据,惨案连连

标签: #socket编程难吗