博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOCP (关于WSASend,WSARecv调用)
阅读量:6220 次
发布时间:2019-06-21

本文共 4322 字,大约阅读时间需要 14 分钟。

hot3.png

最近都在做windows socket相关的东西,使用IOCP其中还是遇到了一些问题,当然遇到问题就要尝试解决问题,这也是一个学习的过程。

IOCP可以说是windows 上性能最好的网络模型了,具体IOCP,就不介绍了,Google,baidu一下,你就知道了。

玉哥在用我的网络接口,发大量数据时,发现,数据对不上,即收包量会增多,内容是不会丢的,由于我是严格控制服务器端的收包大小,和收包量,所以也感觉很奇怪。

先是怀疑WSASend连续调用,会有问题,但大致看了看这篇文章(),这文章写的很给力,所以又觉得不会有问题,于是我就自己开始写了一个测试程序。

当然也不是写了就马上能发现问题,调了一下午加一个晚上,发现了问题所在。

问题在WSARecv,这个东西它居然没填满我要求的缓存,就给完成端口发了通知,导致客户端发过来的数据,被截开了,所以包的数量就增加了,但是由于是TCP,所以内容,顺序都没问题。

接下来说说如何解决问题:

BOOL bIORet = GetQueuedCompletionStatus(CompPort,

                                    &dwIoSize,

                                    (LPDWORD)&pCompletionKey,

                                    &lpOverlapped,

                                    INFINITE);

关键看第二个参数,dwIoSize,它告诉你,你实际接收到了多少数据,通过它,你就应该知道还要继续接受多少数据了吧,明白人,应该就知道该如何做了,不明白的看我的代码吧。

 

注意:WSARecv,最好不要连续调用,特别是在多线程里连续调用,因为后果可能会无法预料,这个应该还是根据需求而定,也许有的情况下可以。

 

剩下的就是贴代码了,时间紧任务重,加上本人比较水,所以代码质量不高,多多包涵,同时还请各位朋友给出建议,提出批评,大家一起学习,共同进步。

client:

#include
#include
#include
#include
#include
using namespace std; #define BUF_TIMES 10 struct CompletionKey{SOCKET s;}; typedef struct io_operation_data { WSAOVERLAPPED overlapped; //重叠结构 WSABUF wsaBuf; //发送接收缓冲区 }IO_OPERATION_DATA, *PIO_OPERATION_DATA; SOCKET sClient; //char (*data)[1024]; DWORD WINAPI ServiceThreadProc(PVOID pParam); int main() { HRESULT hr=CoInitializeEx(NULL,COINIT_MULTITHREADED); if(FAILED(hr)) { MessageBox(NULL,_T("Initialize COM failed!"),_T("error"),MB_OK); //cout<<"Initialize COM failed!"<
wsaBuf.buf,10240*5); fos<
wsaBuf.buf=a[count]; pIO->wsaBuf.len=10240*5; //Sleep(30); if(WSASend(sClient,&(pIO->wsaBuf),1,&sendBytes,flags,&(pIO->overlapped),NULL)== SOCKET_ERROR) { if(ERROR_IO_PENDING != WSAGetLastError())//发起重叠操作失败 { cout<<"send failed"<

server:

#include
#include
#include
#include
#include
#include
using namespace std; #define BUF_TIMES 10 struct CompletionKey{SOCKET s;}; typedef struct io_operation_data { WSAOVERLAPPED overlapped; //重叠结构 WSABUF wsaBuf; //发送接收缓冲区 }IO_OPERATION_DATA, *PIO_OPERATION_DATA; int main() { HRESULT hr=CoInitializeEx(NULL,COINIT_MULTITHREADED); if(FAILED(hr)) { MessageBox(NULL,_T("Initialize COM failed!"),_T("error"),MB_OK); //cout<<"Initialize COM failed!"<
m_sListen); //return false; } retVal=listen(sListen,5); if(SOCKET_ERROR==retVal) { MessageBox(NULL,_T("listen error!"),_T("error"),MB_OK); } sockaddr_in addrClient; int addrLen=sizeof(sockaddr_in); SOCKET sClient=accept(sListen,(sockaddr*)&addrClient,&addrLen); cout<<"come in"<
wsaBuf.buf=new char[10240*5]; pIO->wsaBuf.len=10240*5; if (WSARecv(sClient,&(pIO->wsaBuf),1,&recvBytes,&flags,&(pIO->overlapped),NULL) == SOCKET_ERROR) { if(ERROR_IO_PENDING != WSAGetLastError()) { cout<<"recv failed"<
vecCache; ofstream fos; fos.open("s.txt"); while(1) { BOOL bIORet = GetQueuedCompletionStatus(CompPort, &dwIoSize, (LPDWORD)&pCompletionKey, &lpOverlapped, INFINITE); //失败的操作完成 if (FALSE == bIORet && NULL != pCompletionKey) { //客户端断开 } //成功的操作完成 if(bIORet && lpOverlapped && pCompletionKey) { pIO = CONTAINING_RECORD(lpOverlapped,IO_OPERATION_DATA,overlapped); if(dwIoSize
wsaBuf.len) { vecCache.push_back(pIO); int size=pIO->wsaBuf.len; pIO->wsaBuf.len=dwIoSize; pIO=new IO_OPERATION_DATA; ZeroMemory(pIO, sizeof(IO_OPERATION_DATA)); pIO->wsaBuf.buf=new char[size-dwIoSize]; pIO->wsaBuf.len=size-dwIoSize; if (WSARecv(sClient,&(pIO->wsaBuf),1,&recvBytes,&flags,&(pIO->overlapped),NULL) == SOCKET_ERROR) { if(ERROR_IO_PENDING != WSAGetLastError()) { cout<<"recv failed"<
::iterator it=vecCache.begin(); it!=vecCache.end();it++) { memcpy(p+size,(*it)->wsaBuf.buf,(*it)->wsaBuf.len); size+=(*it)->wsaBuf.len; //清理资源 delete []((*it)->wsaBuf.buf); delete (*it); } memcpy(p+size,pIO->wsaBuf.buf,pIO->wsaBuf.len); count++; fos.write(p,10240*5); fos<
wsaBuf.buf); delete pIO; delete []p; } else { count++; fos.write(pIO->wsaBuf.buf,10240*5); fos<
wsaBuf.buf); delete pIO; } pIO=new IO_OPERATION_DATA; ZeroMemory(pIO, sizeof(IO_OPERATION_DATA)); pIO->wsaBuf.buf=new char[10240*5]; pIO->wsaBuf.len=10240*5; if (WSARecv(sClient,&(pIO->wsaBuf),1,&recvBytes,&flags,&(pIO->overlapped),NULL) == SOCKET_ERROR) { if(ERROR_IO_PENDING != WSAGetLastError()) { cout<<"recv failed"<

 

 

 

 

 

 

转载于:https://my.oschina.net/u/1426828/blog/1795137

你可能感兴趣的文章
Xshell_4.0绿色版
查看>>
PHP&Apache配置多个域名解析的配置方法
查看>>
JavaScript实用资源
查看>>
Linux pipe
查看>>
difference between -Xss and -XX:ThreadStackSize
查看>>
Linux 下编译安装 NGiNX
查看>>
linux if 命令判断条件总结
查看>>
二叉树
查看>>
赋予用户库的读写权限
查看>>
PHP取得用户真实IP
查看>>
XML文档语法 学习笔记
查看>>
组织级安全编码实践
查看>>
国内外SNS比较分析
查看>>
谈PCIe ssd在数据库优化中的作用
查看>>
《Android移动网站开发详解》
查看>>
JTListView
查看>>
android getResources的作用
查看>>
指示器随机变量
查看>>
ubuntu14.04安装Scrapy爬虫
查看>>
Ubuntu 16.04 source.list content
查看>>