WSASend的新发现,与大家共享,也期望有人提出不同的看法!
最近由于项目的需要,我研究了一下重叠IO for 完成例程,发现网上比较流行的一些说法存在问题:
网上的说法:
1. WSASend 投递的数据缓冲区,如果系统的发送缓冲区不足(包含被设定为0的情况),系统会锁定用户提供的缓冲区(直到完成例程返回,在此期间用户提供的缓冲区不允许被修改)
2. 当完成例程返回的时候说明数据发送完毕!
我的说法:
以上两点经实际测试均是错误的。
对于第一点,我做了一个测试程序,发送的过程是这样的
1. 客户端连接到服务器。
2. 客户端向服务器发送一个字符串,内容为 "hello"
3. 设置用于发送数据给客户端的套接字的缓冲区为 0(不设置的结果和设置的结果一样)
4. 服务器接收到客户端发送的"hello"后发送一个大小为 10240000 字节的数据(在栈上的变量)给客户端,内容全部为 "1", 然后我调用 WSASend 发送这个字符串
5. WSASend返回 WSA_IO_PENDING 后我立即修改发送数据中第 4098 位置的一个字符为 "2"。
6. 客户端循环接收数据直到长度为 10240000字节。
结果: 有时客户端收到数据的第 4098 位置不为字符 "1" 为修改后的字符 "2"
结论: 这说明 WSASend 在系统发送缓冲区不足的情况下会锁定内存的结论是错误的,不然用户不会接受到修改后的数据。
对于第二点:
同样是哪个测试程序只是将发送的数据改成了3个字节,我在服务器调用WSASend的位置设置了端点,然后当服务器程序执行到这里的时候我拔掉客户端的网线,然后继续执行服务器程序。
结果: 此时完成例程依旧被调用,而且发送的字节数显示为 3 且用GetLastError 返回的错误码为 0。
结论: 这说明 WSASend 调用后完成例程返回成功不代表数据发送成功,而仅仅代表数据被投递到系统的发送缓冲区而已。
***********************************************************************
这就是我网上比较流行的两种说明的测试结果,个人认为应该比较说明问题,如果哪位大人认为不对,可以在此讨论一下。
期待大家的批评指正。