这两天在写一个程序, 通过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. 思维还不够灵活,改写或者移植程序容易出错, 而且排错能力必须加强