select udp 接收多路数据 错误 无法正确接收数据

Posted on 2014-02-13 11:55  sirius_xu  阅读(786)  评论(0编辑  收藏  举报

 

这两天在写一个程序, 通过select + udp 接收多路数据, 但是却出现了一个错误, 卡了好久, 最终解决,

于是写出来跟大家分享一下, 大牛勿喷。

我之前写过一个select + udp接收数据的情况, 但是仅仅是对于单个接收地址的, 也只是为了学习select的

用法而写的程序, 一切正常,关于源码网上有很多, 就不在这里放出来了。

但是在多个接收地址的时候就出问题了, 问题是:数据还是能收到, 但是不全, 而且数据包有异常,跟预测

结果不一致

最后发现问题的所在是在select检测到有数据进来时的处理不当, 以下是正确的代码截图

说明:sockfd为套接字数组,已在之前创建好, 且都已经绑定好接收地址, tv为timeval结构体, 测试时置为NULL也可以,若需要的话一定要在

每次select之前重新设置, 因为select之后会改变tv的值, fds为select时用到的文件描述符集合,在之前已经用FD_SET与sockfd的各个元素关联,

tmp_fs则是fds 的一个复制, 因为每次select都会破坏tmp_fs,所以在调用时要用副本来替代

由图可看出在select发现有数据进入之后 的处理中 用了两个for循环, 第一个是轮询判断 是哪个套接字收到了数据, 而第二个

则是选择需要用哪个套接字来接收数据, 只有在 select 的标志集合中的变量 i 与 需要接收的套接字数组编号 j 一致时, 才接

收数据, 否则将继续轮询;

而我的问题就卡在这里, 我沿用之前一个套接字的思想只用了一个for循环来判别, 这就导致程序每次都只会判断第一个套接字

是否收到数据, 而当其他的网口接收数据之后却没进行处理, 从而出现了错误。

 

反思:

  1. 对select机制完全不熟悉是导致这个错误出现的最主要最直接的原因

  2. 思维还不够灵活,改写或者移植程序容易出错, 而且排错能力必须加强

Copyright © 2024 sirius_xu
Powered by .NET 8.0 on Kubernetes