user-0 提问: MSG_PEEK参数失效

回复:
user: user-1
content: 引用 2 楼 u012232386 的回复:难道我又进错地了？90分都没人回答？就这么多了，满意瞬结  这个只是一个预读参数而已！会预读出数据，来确定数据大小，合理分配缓存大小！ 数据还是在发送队列里的，后面你再次读取数据的时候也会读到这些数据的！所以只是一个预读功能！

user: user-0
content: 难道我又进错地了？90分都没人回答？就这么多了，满意瞬结

user: user-0
content: up it by myself, thanks

user: user-2
content: 查MSDN是Windows程序员必须掌握的技能之一。 mk:@MSITStore:C:\MSDN98\98VS\2052\kb.chm::/Source/winnt/q147714.htm  Windows Sockets 2 Service Provider Interface Limitations Last reviewed: October 15, 1997 Article ID: Q147714   The information in this article applies to:  Microsoft Windows NT Workstation versions 3.5, 3.51, and 4.0  Microsoft Windows NT Server versions 3.5, 3.51, and 4.0    SUMMARY The Windows Sockets 2 Service Provider Interface (Revision 2.1.0) provides specifications for transport network programming under Windows. This interface is the most comprehensive open transport API designed to date. However, few limitations exist. The purpose of this article is to list and describe the limitation items of the specifications and provide alternative solutions to work around the limitation items. The information below is contributed by the Windows Sockets Vendor Community.     MORE INFORMATION …… 12.Polling with recv(MSG_PEEK) to determine when a complete message has arrived.     Reason and Workaround not available. …… 24.Polling with ioctlsocket(FIONREAD) on a stream socket until a complete "message" appears.     Reason: A stream socket (TCP) does not preserve message boundaries     (please see item 18 above). An application that uses ioctlsocket()     FIONREAD or recv(MSG_PEEK) to wait for a complete "message" to arrive     may not succeed. One reason is due to the internal WinSock system     buffering. If the bytes in a "message" straddle a system buffer     boundary, the WinSock does not report bytes that exist in other     buffers.      Workaround: Do not use peek reads. Read data into your application     buffers and examine it there. ……

user: user-2
content: A stream socket (TCP) does not preserve message boundaries     (please see item 18 above). An application that uses ioctlsocket()     FIONREAD or recv(MSG_PEEK) to wait for a complete "message" to arrive     may not succeed. One reason is due to the internal WinSock system     buffering. If the bytes in a "message" straddle a system buffer     boundary, the WinSock does not report bytes that exist in other     buffers.        Workaround: Do not use peek reads. Read data into your application     buffers and examine it there.

user: user-0
content: 引用 13 楼 angel_su 的回复:2次GetSocket()确定一样吗，只调用一次用个变量记住试试...  是一样的，相同的套接字 ubunto我测试过了，正常 vc2010过不了，我怀疑会不会是 winsock这套，我做设置给搞坏了

user: user-3
content: 2次GetSocket()确定一样吗，只调用一次用个变量记住试试...

user: user-2
content: char response[4096], *pstr = NULL; int readsize;  memset(response, 0, sizeof(response)); if((readsize = RECV(GetSocket(), response, sizeof(response)-4, MSG_PEEK)) <= 0) {     printf("readsize = %d <=0 !\n");     return -1; } if((pstr = strstr(response, "\r\n\r\n")) == NULL) {     printf("strstr(response, \"\\r\\n\\r\\n\")) == NULL !\n");     return -1; } printf("readsize = %d, PEEK response = [%s]\n\n\n", readsize, response);  memset(response, 0, sizeof(response)); if(RECV(GetSocket(), response, readsize, 0) != readsize) {     printf("RECV(GetSocket(), response, readsize, 0) != readsize\n");     return -1; } printf("READ response = [%s]\n\n\n", response);

user: user-0
content: 引用 10 楼 zhao4zhong1 的回复:不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html  ......测过了，用的ubuntu没问题，vc2010就不行

user: user-2
content: 不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

user: user-0
content: 引用 8 楼 user-4 的回复:[quote=引用 7 楼 user-4 的回复:] if((readsize = RECV(GetSocket(), response, sizeof(response)-4, MSG_PEEK)) < 0) return -1; if((pstr = strstr(response, "\r\n\r\n")) == NULL) return -1;  strstr之前你至少将你的http请求当前读到的部分封一个\0结尾吧。  楼主的用意就是先peek看看有有\r\b\r\n不，有了再把header+body的4字节读进来，目前看来只有strstr这里会有问题，。  噢噢，不是读body，是读\r\n\r\n。[/quote]  对，就是查看有没有\r\n\r\n， 有的话 把header+\r\n\r\n 拿出来，不要动body内容

user: user-4
content: 引用 7 楼 user-4 的回复:if((readsize = RECV(GetSocket(), response, sizeof(response)-4, MSG_PEEK)) < 0) return -1; if((pstr = strstr(response, "\r\n\r\n")) == NULL) return -1;  strstr之前你至少将你的http请求当前读到的部分封一个\0结尾吧。  楼主的用意就是先peek看看有有\r\b\r\n不，有了再把header+body的4字节读进来，目前看来只有strstr这里会有问题，。  噢噢，不是读body，是读\r\n\r\n。

user: user-4
content: if((readsize = RECV(GetSocket(), response, sizeof(response)-4, MSG_PEEK)) < 0) return -1; if((pstr = strstr(response, "\r\n\r\n")) == NULL) return -1;  strstr之前你至少将你的http请求当前读到的部分封一个\0结尾吧。  楼主的用意就是先peek看看有有\r\b\r\n不，有了再把header+body的4字节读进来，目前看来只有strstr这里会有问题，。

user: user-0
content: 引用 5 楼 max_min_ 的回复:[quote=引用 4 楼 u012232386 的回复:] [quote=引用 3 楼 max_min_ 的回复:] [quote=引用 2 楼 u012232386 的回复:] 难道我又进错地了？90分都没人回答？就这么多了，满意瞬结  这个只是一个预读参数而已！会预读出数据，来确定数据大小，合理分配缓存大小！ 数据还是在发送队列里的，后面你再次读取数据的时候也会读到这些数据的！所以只是一个预读功能！ [/quote] 我知道是预读的功能，但是我预读玩了之后，再读取的时候，前面预读的那些数据确实是没了，不再底层接收缓冲区中了[/quote] 不会吧？是不是那里代码处理出了问题？重新读取数据的时候，不是预读的数据？[/quote]  我也是怀疑会不会是代码哪里没处理好，但是查了一上午也没找出什么不对的地

user: user-1
content: 引用 4 楼 u012232386 的回复:[quote=引用 3 楼 max_min_ 的回复:] [quote=引用 2 楼 u012232386 的回复:] 难道我又进错地了？90分都没人回答？就这么多了，满意瞬结  这个只是一个预读参数而已！会预读出数据，来确定数据大小，合理分配缓存大小！ 数据还是在发送队列里的，后面你再次读取数据的时候也会读到这些数据的！所以只是一个预读功能！ [/quote] 我知道是预读的功能，但是我预读玩了之后，再读取的时候，前面预读的那些数据确实是没了，不再底层接收缓冲区中了[/quote] 不会吧？是不是那里代码处理出了问题？重新读取数据的时候，不是预读的数据？

user: user-0
content: 引用 3 楼 max_min_ 的回复:[quote=引用 2 楼 u012232386 的回复:] 难道我又进错地了？90分都没人回答？就这么多了，满意瞬结  这个只是一个预读参数而已！会预读出数据，来确定数据大小，合理分配缓存大小！ 数据还是在发送队列里的，后面你再次读取数据的时候也会读到这些数据的！所以只是一个预读功能！ [/quote] 我知道是预读的功能，但是我预读玩了之后，再读取的时候，前面预读的那些数据确实是没了，不再底层接收缓冲区中了