IOCP模式中,在socket上同时投递WSARecv和WSASend的问题? [问题点数:50分]

Bbs3
本版专家分:742
结帖率 98.95%
Bbs10
本版专家分:139143
Blank
进士 2018年总版新获得的技术专家分排名前十
Blank
银牌 2019年7月 总版技术专家分月排行榜第二
2019年5月 总版技术专家分月排行榜第二
Blank
铜牌 2019年8月 总版技术专家分月排行榜第三
2019年4月 总版技术专家分月排行榜第三
2019年3月 总版技术专家分月排行榜第三
Blank
红花 2019年8月 VC/MFC大版内专家分月排行榜第一
2019年7月 VC/MFC大版内专家分月排行榜第一
2019年6月 VC/MFC大版内专家分月排行榜第一
2019年5月 VC/MFC大版内专家分月排行榜第一
2019年4月 VC/MFC大版内专家分月排行榜第一
2019年3月 VC/MFC大版内专家分月排行榜第一
2019年1月 VC/MFC大版内专家分月排行榜第一
2018年12月 VC/MFC大版内专家分月排行榜第一
2018年11月 VC/MFC大版内专家分月排行榜第一
2018年10月 VC/MFC大版内专家分月排行榜第一
2018年9月 VC/MFC大版内专家分月排行榜第一
2018年8月 VC/MFC大版内专家分月排行榜第一
2018年5月 VC/MFC大版内专家分月排行榜第一
2018年4月 VC/MFC大版内专家分月排行榜第一
2018年3月 VC/MFC大版内专家分月排行榜第一
2018年2月 VC/MFC大版内专家分月排行榜第一
2018年1月 VC/MFC大版内专家分月排行榜第一
2017年12月 VC/MFC大版内专家分月排行榜第一
2017年11月 VC/MFC大版内专家分月排行榜第一
2017年7月 VC/MFC大版内专家分月排行榜第一
2012年7月 VC/MFC大版内专家分月排行榜第一
Bbs3
本版专家分:742
Bbs3
本版专家分:742
Bbs10
本版专家分:139143
Blank
进士 2018年总版新获得的技术专家分排名前十
Blank
银牌 2019年7月 总版技术专家分月排行榜第二
2019年5月 总版技术专家分月排行榜第二
Blank
铜牌 2019年8月 总版技术专家分月排行榜第三
2019年4月 总版技术专家分月排行榜第三
2019年3月 总版技术专家分月排行榜第三
Blank
红花 2019年8月 VC/MFC大版内专家分月排行榜第一
2019年7月 VC/MFC大版内专家分月排行榜第一
2019年6月 VC/MFC大版内专家分月排行榜第一
2019年5月 VC/MFC大版内专家分月排行榜第一
2019年4月 VC/MFC大版内专家分月排行榜第一
2019年3月 VC/MFC大版内专家分月排行榜第一
2019年1月 VC/MFC大版内专家分月排行榜第一
2018年12月 VC/MFC大版内专家分月排行榜第一
2018年11月 VC/MFC大版内专家分月排行榜第一
2018年10月 VC/MFC大版内专家分月排行榜第一
2018年9月 VC/MFC大版内专家分月排行榜第一
2018年8月 VC/MFC大版内专家分月排行榜第一
2018年5月 VC/MFC大版内专家分月排行榜第一
2018年4月 VC/MFC大版内专家分月排行榜第一
2018年3月 VC/MFC大版内专家分月排行榜第一
2018年2月 VC/MFC大版内专家分月排行榜第一
2018年1月 VC/MFC大版内专家分月排行榜第一
2017年12月 VC/MFC大版内专家分月排行榜第一
2017年11月 VC/MFC大版内专家分月排行榜第一
2017年7月 VC/MFC大版内专家分月排行榜第一
2012年7月 VC/MFC大版内专家分月排行榜第一
Bbs3
本版专家分:742
Bbs3
本版专家分:742
Bbs2
本版专家分:233
Bbs6
本版专家分:8843
Bbs5
本版专家分:2983
Bbs2
本版专家分:233
Bbs12
本版专家分:361543
版主
Blank
名人 2013年 荣获名人称号
Blank
探花 2011年 总版技术专家分年内排行榜第三
2010年 总版技术专家分年内排行榜第三
Blank
进士 2012年 总版技术专家分年内排行榜第五
Blank
金牌 2012年1月 总版技术专家分月排行榜第一
Bbs1
本版专家分:40
Bbs1
本版专家分:40
WSASend和WSARecv函数问题
WSASend 和 WSARecv函数里有个标志位参数,这个参数起什么作用?是否受流式和非流式的影响?rn  如果要让他可靠地接收或发送数据,是否就是检查到错误时就不断的发送或不断的接收?如果真这样,程序不就陷入了死循环中吗?rnrn多谢指教
讨论一下WSARecv和WSASend的问题
这两个函数都可以<em>投递</em>多个WSABUF的缓冲区,,大家讨论以下这样做一般用在什么情况下比较适合?rn对提高网络服务端程序的响应性能有多大改善?rnrn
WSARecv() 和 WSASend()的问题
WSARecv()在加了Overlapped参数后,一定要等这次的overlapped操作成功后才能调用WSASend(),否则会有WSAENOTSOCK错误。rn请问怎么样才能立刻完成上一次的WSARecv()操作?
关于WSASend和WSARecv的问题
WSASend( s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesSent : DWORD; dwFlags : DWORD;rnrnlpBuffers的数据结构是什么?如何才能解出里面发送的数据?
IOCP中关于投递0字节缓冲区WSARecv的问题
windows网络编程上说,”为了防止ENOBUFS错误,可以先<em>投递</em>一个0字节的缓冲区的接收操作,,一旦0字节接收操作完成,服务器就可以实施非阻塞接收,以获得所有数据”。请问<em>投递</em>了一个0字节缓冲区的WSARecv之后,程序里接下来该怎么做?最好能简单的写一点代码!
iocp完成端口问题,在投递WSASend后client的WSARecv没有返回,无法接受数据
我刚开始采用<em>iocp</em>完成端口开发<em>socket</em>服务器端程序。rnrn用vc写了一个client的测试程序。结果该测试程序在debug时,recv和send数据一切正常,但在release下send正常,recv不返回。rnrn以上<em>问题</em>到底是服务器端错误,还是client端的<em>问题</em>啊。
IOCP模型中,WSASend投递失败的话,如何处理缓冲区?
如题,是在<em>投递</em>失败后立刻进行科处理,还是完成端口会收到通知,在完成端口中处理(<em>投递</em>失败的话,完成端口应该收不到通知的吧)?
IOCP中WSASend投递成功但GetQueuedCompletionStatus不返回的证据
各位,不知道大家有遇到过IOCP中WSASend<em>投递</em>成功但GetQueuedCompletionStatus不返回的情况没,我是通过一个client端不断的测试该<em>iocp</em>服务器程序后得到的结论;rnrn我这个client端测试程序会不停的连服务器程序,然后随机断开某些<em>socket</em>,然后再重新连如此反复,连上的<em>socket</em>会给<em>iocp</em>服务器程序发送一些数据包,接收服务器原样发回的数据包,总之就是个测试<em>iocp</em>服务器程序是否能够支持相对多有一点连接(1000-2000连接)、是否够健壮的一个client端程序,服务器也会在一定的时间(20秒)内对依然连接进来的<em>socket</em>进行强制踢出close<em>socket</em>操作;rnrn按照消息约定格式,我收到一个消息后入消息队列,通知线程池中线程去处理,处理后把消息扔到发送消息队列(这里我是原样把收到的消息发送到发送消息队列),然后系统中有专门的一个线程负责将发送消息队列中的消息用WSASend发送出去,我分别对recv和send做计数,保证同一时刻只有一个recv和一个send,完成并返回后再<em>投递</em>新的WSARecv或者WSASend();rnrn对于GetQueuedCompletionStatus()返回的失败信息,凡是和SEND有关的信息,我都打印出来以供识别(发现并没有这些SEND信息出现,也就是说,除WSASend()发送完成的通知通过GetQueuedCompletionStatus()正常返回外,没有发现返回的和<em>投递</em>WSASend有关的异常或者错误信息;rnrn当收到GetQueuedCompletionStatus()返回的失败或者成功且字节为0的信息(说明对方或者自己方close<em>socket</em>),我把该<em>socket</em>相关的上下文结构扔到一个队列去,该队列不释放资源只用于观察,发觉该队列中确实有挂起的WSASend()没有返回,并且等待了10几分钟依然没有返回,所以,我得到的结论是IOCP中WSASend<em>投递</em>成功但可能在某些极端的情况下(比如client突然断开,或者我突然在某个单独的线程中把该client踢出去(close<em>socket</em>)等比较复杂的网络情况下,导致WSASend<em>投递</em>成功但GetQueuedCompletionStatus不返回针对该WSASend<em>投递</em>的结果信息;rnrn在我程序的书写中,虽然频繁的连接,断开,频繁的收发数据包,但这种WSASend<em>投递</em>成功但GetQueuedCompletionStatus不返回的情况依然非常罕见(大概1小时才出现一次)。rnrn这里想请教各位,是否有朋友也进行过这方面的测试,确认WSASend<em>投递</em>成功在某种极端的情况下确实会导致GetQueuedCompletionStatus不返回和该WSASend<em>投递</em>有关的回馈信息,也欢迎大家讨论该<em>问题</em>;rn
IOCP 的WSARecv问题
(为简化起见,1个数字对应1个x或- )rnrn比如说将有如下数据被传送到达: 101xx102xxxx103xxxxxx rnrn现在<em>投递</em>了5个WSARecv(),其buf按顺序如下: rnrnrn Recv1.buf Recv2.buf Recv3.buf Recv4.buf Recv5.bufrnrn -------- | -------- | -------- | -------- | --------rnrn理想情况下应该是这样:rnrn Recv1.buf Recv2.buf Recv3.buf Recv4.buf Recv5.bufrnrn 101xx102 | xxxx103x | xxxxx--- | -------- | --------rnrn<em>问题</em>一:会不会出现这种情况:rn rn 中间有的WSARecv没装满buf就返回完成了,余下数据被下个WSARecv接着收:rn Recv1.buf Recv2.buf Recv3.buf Recv4.buf Recv5.bufrnrn 101xx102 | xxxx---- | 103xxxxx | x------- | --------rn rn或者返回是乱序的?:rnrn Recv2.buf Recv1.buf Recv3.buf Recv4.buf Recv5.bufrnrn xxxx103x | 101xx102 | xxxxx--- | -------- | --------rnrn<em>问题</em>二:这包该怎么拆啊?我想这样子处理包rnWORD type;rntype=取得包的类型;rnswitch(type)rnrn case 101:On101();break;//处理101命令rn case 102:On102();break;//处理102命令rn...rnrn有些不定长度的单个数据流比WSARecv()里准备的buf还大,该怎么办呢?
[完成端口]AccpetEx ,WSASend, WSARecv 在完成端口的工作者线程中投递,与在其它线程中投递有什么区别?
完成端口一般会创建 2 * cpu 个数 + 2 个工作者线程。rnAccpetEx ,WSASend, WSARecv 在完成端口的工作者线程中<em>投递</em>,与在工作者线程之外的线程中<em>投递</em>有什么区别?
WSASend投递大量数据~~
我写了一个文件传输程序rnrn结构很简单,每次读取一定字节的数据然后发送出去~~rnrn假如说,我定义的buf大小为1024,如果一个文件为1024*10rnrn那么我就需要发送10次,调用10次WSASend进行数据发送~~rnrn如果说我定义一个WSABUF buf[10]的数组,将这个文件全部放入这个buf中rnrn然后将这个buf数组<em>投递</em>出去,是否可行~~rnrn当然,这个例子的数据很小了~~rnrn应该是可以发送成功的,假如这个文件有100M,如果buf大小为1024*4,那么我需要<em>投递</em>上万次,是不是会影响效率~~rnrn如果我每次读取1M的数据,用刚才的方法<em>投递</em>出去,那么就可以较少<em>投递</em>次数~~rnrn但是我刚才写了一个简单的测试程序,发现这样<em>投递</em>数据,接收端好像会接收不完整,发送端已经显示发送出去这么多数据,但是接收端只收到一部分数据~~~rnrn所以来问问,我说的这个方法是否可行~~~rnrn
在哪里投递WSASend好呢?
我是在GetQueuedCompletionStatus后得到前一个WSASend<em>投递</em>完成了再投第二个好呢?rn还是在另外一个线程中一直<em>投递</em>,然后再在GetQueuedCompletionStatus后判断时候WSASend的很完整好呢?rnrn请求高手来!!
WSARecv()投递到完成端口中的问题(100分)
<em>socket</em>和服务器端连接成功并和完成端口绑定后,设置了SO_RCVTIMEO为指定的时间。当<em>投递</em>了一个WSARecv()后,服务器不发送任何数据给<em>socket</em>,完成端口始终没有因为接收超时而返回。rn1、是不是使用IOCP模型SO_RCVTIMEO就不起作用了?rn2、如果起作用,怎么超时接收后不返回?
完成例程中投递WSARecv的问题
我用accept得到的<em>socket</em>句柄<em>投递</em>WSARecv后,回调函数正确被调用,但用connect得到的句柄<em>投递</em>后回调函数无响应,不知道为什么,请高人指教.
大家讨论一下完成端里在同一个套接字上同时投递一个WSARecv和WSASend的问题
当<em>同时</em>在同一个连接上发出WSASend和WSARecv调用的时候,这个连接相关单IO数据该如何处理才好?是共用一个还是各自分配一个?我比较倾向用同一个,但是这中间涉及到比较复杂的同步<em>问题</em>,如果用两个的话,在很多连接的情况下,开销太大。。。rnrn大家来讨论讨论。。
请教IOCP,connectex返回WSA_IO_PENDING,是不是就可以投递WSARECV了?
如题
IOCP实现数据收发时如何控制WSASend和WSARecv
我在实现中WSASend和WSARecv独立<em>投递</em>,在通过GetQueuedcompletionStatus处理时发现仅通过一个OPCode区分WSASend和WSARecv存在<em>问题</em>,收发流量在统计时发生了混乱,望高人指点,如何<em>投递</em>收发,如何区分收发等,谢谢!
iocp 连续调用WSASend问题
我自己写了个<em>iocp</em>程序 但是在连续给同个客户端发包 造成第二个包没发出去rn不知道如何处理 rn本人主要代码如下rnDWORD WINAPI ServerThreadFunc(LPVOID lpParam)rnrn CHuanshouDlg *lp = (CHuanshouDlg *)lpParam;rn WSADATA wsaData;rn HANDLE hCompPort;rn DWORD ThreadID;rn DWORD Ret;rn if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)rn rn AfxMessageBox("WSAStartup failed with error!");rn return 0;rn rn if ((hCompPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)rn rn AfxMessageBox("CreateIoCompletionPort failed with error!");rn return 0;rn rn SYSTEM_INFO SystemInfo;rn GetSystemInfo(&SystemInfo);rn unsigned cpu = SystemInfo.dwNumberOfProcessors*2;rn for(unsigned int i=0; i < cpu; i++)rn rn HANDLE ThreadHandle;rn lpthreadParam p = new _THREADPARAM;rn p->cpid = hCompPort;rn p->lp = lp;rn //if ((ThreadHandle = CreateThread(NULL, 0, WorkThread, hCompPort, 0, &ThreadID)) == NULL)rn if ((ThreadHandle = CreateThread(NULL, 0, WorkThread, p, 0, &ThreadID)) == NULL)rn rn AfxMessageBox("CreateThread() failed with error");rn return 0;rn rn CloseHandle(ThreadHandle);rn rn SOCKET ListenSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, WSA_FLAG_OVERLAPPED);rn SOCKADDR_IN ServerAddr;rn ServerAddr.sin_family = AF_INET;rn ServerAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);rn ServerAddr.sin_port = htons(8888);rn bind(ListenSocket,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr));rn listen(ListenSocket,100);rn rn SOCKADDR_IN ClientAddr;rn int addr_length=sizeof(ClientAddr);rn while (TRUE)rn rn LPSOCKET_INFORMATION SI = new SOCKET_INFORMATION();rn if ((SI->Socket = WSAAccept(ListenSocket,(SOCKADDR*)&ClientAddr, &addr_length,NULL,0)) != INVALID_SOCKET)rn rn //初始化一个新的用户信息rn memset(&SI->Overlapped,0,sizeof(WSAOVERLAPPED));rn memset(SI->buffer, 0, DATA_BUFSIZE);rn SI->RecvDataBuf.buf = SI->buffer;rn SI->RecvDataBuf.len = DATA_BUFSIZE;rn SI->SendDataBuf.buf = SI->buffer;rn SI->SendDataBuf.len = DATA_BUFSIZE;rn SI->IoType = IORECV;rn SI->ClientName = "null";rn SI->firstlog = true;rn InitializeCriticalSection(&SI->single_cs);rn rn if (CreateIoCompletionPort((HANDLE)SI->Socket, hCompPort, (DWORD)SI, 0) == NULL)rn rn AfxMessageBox("CreateIoCompletionPort failed with error ");rn return 0;rn rn //send a I/O requestrn if(WSARecv(SI->Socket, &SI->RecvDataBuf, 1, &Bytes, &Flags, &SI->Overlapped, NULL) == SOCKET_ERROR)rn rn if(WSAGetLastError() != WSA_IO_PENDING)rn rn AfxMessageBox("disconnect\n");rn shutdown(SI->Socket,SD_SEND);rn close<em>socket</em>(SI->Socket); rn delete SI;rn continue;rn rn rn rn rn return 0;rnrnrn/// rn/// I/O工作线程rn/// rnDWORD WINAPI WorkThread(LPVOID CompletionPortID)rnrn //HANDLE hCompPort = (HANDLE)CompletionPortID;rn lpthreadParam p = (lpthreadParam)CompletionPortID;rn HANDLE hCompPort = (HANDLE)p->cpid; rn CHuanshouDlg *lp = (CHuanshouDlg *)p->lp;rn while (TRUE)rn rn DWORD BytesTransferred = 0;rn LPSOCKET_INFORMATION SI = NULL;rn LPWSAOVERLAPPED Overlapped = NULL;rnrn //Threads pool,waiting for awakern BOOL t = GetQueuedCompletionStatus(hCompPort, &BytesTransferred, (LPDWORD)&SI, &Overlapped, INFINITE);rn if (t)rn rn EnterCriticalSection(&SI->single_cs);rn switch(SI->IoType)rn rn case IORECV:rn rn rn if (0 == BytesTransferred)rn rn if(!SI->firstlog)rn rn lp->QuitGame(SI->Socket,SI->ClientName);rn rn continue;rn rn CString message,msg2;rn message = SI->RecvDataBuf.buf;rn if(message == "")rn rn memset(SI->buffer, 0, DATA_BUFSIZE);rn SI->RecvDataBuf.len = DATA_BUFSIZE;rn SI->RecvDataBuf.buf = SI->buffer;rn SI->IoType = IORECV;rn if (WSARecv(SI->Socket, &SI->RecvDataBuf, 1, &Bytes, &Flags, &SI->Overlapped, NULL) == SOCKET_ERROR)rn rn if(WSAGetLastError() != WSA_IO_PENDING)rn rn lp->QuitGame(SI->Socket,SI->ClientName);rn delete SI;rn continue;rn rn rn continue;rn rn int f = -1;rn f = message.Find("\0");rn if(f >= 0)rn rn CString xml = "";rn xml = xml + "";rn xml = xml + "";rn xml = xml + "\0";rn rn sprintf(SI->SendDataBuf.buf,"%s",xml);rn SI->SendDataBuf.len = strlen(xml) + 1;rn SI->IoType = IOSEND; rn //发送策略文件rn if (WSASend(SI->Socket, &SI->SendDataBuf, 1, &Bytes, Flags, &SI->Overlapped, NULL) == SOCKET_ERROR)rn rn if(WSAGetLastError() != WSA_IO_PENDING)rn rn shutdown(SI->Socket,SD_SEND);rn close<em>socket</em>(SI->Socket); rn delete SI;rn continue;rn rn rn rn elsern rn CMarkup xml = CMarkup();rn xml.SetDoc(message);rnrn CString act;rn CString item;rn CString condition;rn item = "msg";rn condition = "act";rn if(xml.FindChildElem(item))rn rn xml.IntoElem();rn act = xml.GetAttrib(condition);rn elsern AfxMessageBox("格式错误:" + SI->ClientName+"->" + message);rn continue;rn rn char* act2 = act.GetBuffer(act.GetLength());rn switch(actMap[act2]) rn rn case login:rn rn condition = "username";rn CString username;rn username = xml.GetAttrib(condition);rn rn //踢掉同名用户rn map::iterator iter;rn EnterCriticalSection(&clients_cs);rn iter = clients.find(username.GetBuffer());rn if(iter != clients.end())rn rn LPSOCKET_INFORMATION oldlp = LPSOCKET_INFORMATION(iter->second);rn if(SI->Socket != oldlp->Socket)rn rn shutdown(LPSOCKET_INFORMATION(iter->second)->Socket,SD_SEND);rn close<em>socket</em>(LPSOCKET_INFORMATION(iter->second)->Socket);rn rn clients.erase(iter);rn rn SI->ClientName = username;rn SI->firstlog = false;rn SI->IoType = IOSEND;rn clients[username] = SI;rn LeaveCriticalSection(&clients_cs);rn lp->loginGame(username);rn rn //接到数据后向客户端发同意登录信息rn CString _msg = "\0";rn SI->SendDataBuf.len = _msg.GetLength() + 1;rn SI->SendDataBuf.buf = _msg.GetBuffer(_msg.GetLength());rn SI->IoType = IOSEND;rn if (WSASend(SI->Socket, &SI->SendDataBuf, 1, &Bytes, Flags, &SI->Overlapped, NULL) == SOCKET_ERROR)rn rn if(WSAGetLastError() != WSA_IO_PENDING)rn rn lp->QuitGame(SI->Socket,SI->ClientName);rn delete SI;rn continue;rn rn rn break;rn rn default:rn rn break;rn rn rn rn break;rn rn case IOSEND:rn rn CString num;rn num.Format("%d",BytesTransferred);rn lp->m_log += "IOSEND:"+ num +"\r\n";rn lp->SendMessage(UPDATA_MESSAGE);rn memset(SI->buffer, 0, DATA_BUFSIZE);rn SI->RecvDataBuf.len = DATA_BUFSIZE;rn SI->RecvDataBuf.buf = SI->buffer;rn SI->IoType = IORECV;rn if (WSARecv(SI->Socket, &SI->RecvDataBuf, 1, &Bytes, &Flags, &SI->Overlapped, NULL) == SOCKET_ERROR)rn rn if(WSAGetLastError() != WSA_IO_PENDING)rn rn lp->QuitGame(SI->Socket,SI->ClientName);rn delete SI;rn continue;rn rn rn break;rn rn default:rn break;rn rn LeaveCriticalSection(&SI->single_cs);rn rn rn return FALSE;rnrnrnbool CHuanshouDlg::SendMessageToOneByName(CString msg,CString username)rnrn EnterCriticalSection(&clients_cs);rn map::iterator iter;rn LPSOCKET_INFORMATION lp;rn iter = clients.find(username.GetBuffer());rn if(iter == clients.end())rn rn LeaveCriticalSection(&clients_cs);rn return false;rn rn lp = (LPSOCKET_INFORMATION)iter->second;rn lp->SendDataBuf.len = msg.GetLength() + 1;rn lp->SendDataBuf.buf = msg.GetBuffer(msg.GetLength());rn lp->IoType = IOSEND;rn Flags = 0;rn if (WSASend(lp->Socket, &lp->SendDataBuf, 1, &Bytes, Flags, &lp->Overlapped, NULL) == SOCKET_ERROR)rn rn shutdown(lp->Socket,SD_SEND);rn close<em>socket</em>(lp->Socket);rn clients.erase(iter);rn LeaveCriticalSection(&clients_cs);rn return false;rn rn LeaveCriticalSection(&clients_cs);rn return true;rnrn/发送系统消息按钮rnvoid CHuanshouDlg::OnBnClickedSend()rnrn rn SendMessageToOneByName("test11\0","bear");rn Sleep(100);rn SendMessageToOneByName("test2\0","bear");rnrnrnrn很奇怪,只要在发送的时候 Sleep(100);就成功rn没有sleep 第二条客户端没有接到rn没有出现沾包情况 客户端只接到第一个包的完整信息rn
关于IOCP投递个数问题
IOCP使用rnDWORD dwBytes = 0;rnDWORD dwRevelen = 0;rnAcceptEx(sClient,pIOBuffer->m_sClient,pIOBuffer->m_pBuffer,dwRevelen,sizeof(sockaddr_in)+16,sizeof(sockaddr_in)+16,&dwBytes,&pIOBuffer->m_ol);rn方式,<em>投递</em>1个pIOBuffer.rn当连接到达时,rnBOOL bIORet = GetQueuedCompletionStatus(hCompletionPort,&dwIoSize,(LPDWORD)&pNetContent,&lpOverlapped, INFINITE);rn根据逻辑,删除当前pIOBuffer,即<em>投递</em>到AcceptEx的pIOBuffer.删除当前对象.完成端口中,不存在AcceptEx所关联的IOBuffer.rn如果客户端再连接到服务端时,完成端口不再触发任何事件.此时,客户端显示链接正常.服务端netstat -an检查链接,发现为启用状态,关闭客户端,为关闭等待.rnrn请问,如何避免上述情况,服务端没有多余资源响应时,禁止连接.或获取到客户端连接事件.
IOCP服务器WSASend的疑惑
MSDN里面的说明:rnThe array of WSABUF structures pointed to by the lpBuffers parameter is transient. If this operation is completed in an overlapped manner, it is the service provider's responsibility to capture these WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays.rnNote The successful completion of a WSASend does not indicate that the data was successfully delivered.rnrn意思是提交的数据在WSASend后就可以挪作他用或销毁,即可以象如下方式调用:rnvoid SendData()rnrnchar data[100];rnsprintf(data,"something to send");rnWSASend(...)rn;rn看起来WSASend是会把数据复制一份自己保存,试了下,分配1M的缓冲区,读取一个三四百K的文本,一次性把数据WSASend出去,然后立马销毁该缓冲区,客户端是能完整收到所有数据的。rn但是我疑惑的是上面MSDN里最后一句话,WSASend不保证数据成功提交,意思是不是这样调用会丢包呢?那就无法体现TCP的可靠性了。这种情况下如果GetQueuedCompletionStatus检测到发送的字节数与要发送的不一致,没办法处理了,因为发送的数据已不存在了。那MSDN又为什么说可以销毁数据呢?rn
怎样实现完成例程的重叠IO模型同时投递一个WSARecv和WSASend请求?
我看过很多完成例程的重叠IO模型的讲解,都是讲<em>投递</em>一个WSARecv请求,请问如何实现<em>同时</em><em>投递</em>一个WSARecv和WSASend请求,谢谢
IOCP关于wsasend和send的问题
现在有这个一个IOCP程序,并发量在1000~2000个客户端左右/每秒,每个客户端的包不大于2K,rn在应答客户端发送内容的时候,每个GET到的<em>socket</em>对象用<em>wsasend</em>还是用send好呢?rn
IOCP WSASend遇到的奇怪问题?
我写了一个IOCP类,用WSASend发送数据,通过rn[code=C/C++] BOOL isOK = GetQueuedCompletionStatus(rn hCompletionPort,rn &dwTrans,rn (LPDWORD) &lpClientContext,rn &lpOverlapped, INFINITE);[/code]获取发送结果。发现有 dwTrans > lpOverlapped->m_wsabuf.len并且lpOverlapped->m_wsabuf.len == 0的情况出现。dwTrans 一般与原来发送的数据长度(lpOverlapped->m_wsabuf.len)相等。<em>问题</em>是lpOverlapped->m_wsabuf.len == 0这是什么原因引起的?另外数据是发送成功还是没有成功呢?rnrn请高手指点。
问个IOCP当中的WSASend的问题
比如说有这样的一个IOCP服务器,他接到client的连接以后就开始给client发送一个文件,每次都从文件里读4K的数据存到一个缓存里头,然后调用WSASend发送给client,如果文件很大需要很长时间才能发送完毕,但是在发送过程当中client由于某些原因断线,这个时候要怎么处理。rnrn我试了下,即使断线WSASend也不会返回WSA_IO_PENDING以外的错误,但是线程池里头的GetQueuedCompletionStatus倒是会返回FALSE,用WSAGetLastError返回的错误也很怪,一个是64一个是995(我一共用了两个线程)。rnrn这种WSASend的情况要如何处理,毕竟我要在WSASend完成的时候delete掉缓存,否则内存泄漏了
IOCP投递I/O问题?
rn 1、创建一个套接字,使用connect连接服务器,rn 2、成功后使用BindIoCompletionCallback将套接字绑定rn rn这样使用正确吗?rn
关于IOCP的WSARecv
小弟初学IOCP,照着网上的源码翻看了很多,自己尝试写了个IOCP模型的服务端,目前有一个地方不解。rnrn我对于接收数据的理解是:WSARecv 是<em>投递</em>一个IO请求 然后通过GetQueuedCompletionStatus 获取缓冲区数据。 - 就是重叠结构,我不解的是 我为什么一执行WSARecv 缓冲区里面就有数据了? 难道不是通过GetQueuedCompletionStatus 获取重叠结构的数据么? - 我看到代码里头每次一接收到数据把缓冲区内容清空后都要再<em>投递</em>一个IO请求 。rnrnrn
IOCP WSASend事件未决
最近发现我的服务器的内存在上涨,经过多次走查代码,终于发现问是所在,我简单描述一下我的应用,望大家帮我解决:rn为了提高效率,我为每个连接都保持了1~3个WSASend请求,如果WSASend过快的话,前一个WSASend中事件未决,马上又<em>投递</em>了另一个,这样维持在2个左右。现在有一个问是,就是我监测这些IO<em>投递</em>过程中,发现存在大量未决事件,即使在某处调用了close<em>socket</em>,那些未决事件仍然未返回,而这些未决事就引起了内存泄漏。rnrn我查了大量资料,都是说close后,该连接的所有IO请求都乖乖地返回,可是我却总是没发现有返回呢?rn(注,我是通过ByteTransferred == 0来判断是否返回的,正确吗?)rnrn困惑了很久,指望你们了!rnrnrn
在线求救:IOCP中WSARecv接收数据问题
完成端口 rn在I/O服务线程中,通过WSARecv接收数据。在本机测试接收一切正常。rn如果通过局域网中的另一台电脑发送数据,WSARecv则接收不了正常的数据。rn如果在WSARecv前 添加一句sleep(1000)。则不论通过那种方式发送接收,都能正常接收数据。rnrn请问一下这是什么<em>问题</em>呢??rn小弟刚接触IOCP 有很多不明白的地方,望各位老大能解惑rn
IOCP WSARecv返回997
各位大侠,是这样的,小弟刚学习IOCP的,客户端发送10000个字符(char)的数据,而接收端每次接收的buf是1024个字符(char),循环接收的时候,WSARecv会返回997的错误码,数据会丢失一部分,为什么呀???
IOCP中使用WSARecv的内存泄露问题
在IOCP中使用WSARecv进行数据包接收 泄露是用Purify检测到的 现象如下:rn1、泄露发生在系统退出时,指示的代码行就是调用WSARecv的那一行,具体在下面是AllocHeap(或HeapAlloc,记不清了)rn2、我可以肯定用来接收的空间已经释放掉了,不是一般的忘记释放的<em>问题</em>;rn3、只发生在系统退出时,如果循环接收若干次,则仍然只有一个泄露;rn4、退出时首先断开了所有连接,2中所说的用来接收的空间就是在这时候通过IOCP检测到连接断开然后释放的,通过debug跟踪以及日志记录,确认已经删除;断开连接后,释放监听<em>socket</em>,监听线程,以及IOCP工作线程;rn 怀疑是调用WSARecv时是否会有一些堆上空间的分配,但没有找到例证;rn 代码很长,没办法写,不好意思了,请各位给点意见吧,或者提供点思路都行.....
重叠I/O完成例程模型如何同时投递WSARecv和WSASend
参考自这篇文章: http://www.win<em>socket</em>dotnetworkprogramming.com/winsock2programming/winsock2advancediomethod5g.html 推荐大家去上面看看,讲得很细致,一步一步都很详细。因为都是英文的,所以坚持吧~下面重点就解释一下其原理,是通过什么方式来使一个完成例程<em>同时</em>处理WSARecv和WSASend的。首先我们
完成端口的TCP控制+WSASend/WSARecv
给定以下伪代码rnrn[code=C/C++]rnrn/*完成端口*/rnHANDLE io_completion_port;rnrn/*TCP链接描述结构*/rntypedef struct connectionrnrn SOCKET <em>socket</em>;rn OVERLAPPED sending;rn OVERLAPPED receiving;rn WSABUF buffer1;rn WSABUF buffer2;rnrn CONNECTION, *PCONNECTION;rnrn/*完成工作线程*/rnvoid worker()rnrn int bytes;rn LPOVERLAPPED overlapped;rn PCONNECTION connection;rn GetQueuedCompletionStatus(io_completion_port, &bytes, &connection, &overlapped, INFINITE);rn /*此后省略处理函数*/rnrnrnvoid main()rnrn/*<em>socket</em>已经加入完成端口io_completion_port*/rnWSARecv(connection-><em>socket</em>, &(connection->buffer1), 1, 0, &flag, &(connection->receiving), 0);rnWSASend(connection-><em>socket</em>, &(connection->buffer2), 1, 0, flag, &(connection->sending), 0);rnrn[/code]rnrn既定目标:实现双工<em>socket</em>rn给定条件:现在,worker阻塞等待中rn遇到<em>问题</em>:rn1.main()中,在同一个<em>socket</em>上的WSARecv和WSASend能否成功(即SOCKET_ERROR&&WSA_IO_PENDING态)?rn2.理论上,给定同一个TCP链接,客户机和服务器都调用WSARecv或者WSASend,完成端口会报错吗?比如A在链接上WSARecv,然后B也在链接上WSARecv。
急,请教WSASend、WSARecv()函数
当我在服务器端用WSASend()、WSARecv()函数发送接受数据时,WSASend()函数、WSARecv()函数的第一个形参SOCKET应该是服务器端的SOCKET还是客户端的SOCKET?
关于IOCP的投递顺序
假设一种情况rnrn我发出两次WSASend,一次<em>投递</em>10字节数据,里面全是a,第二次<em>投递</em>10字节数据,里面全是brnrn我们期待的顺序应该是一共发出去20字节的数据,前10字节是a,后10字节是brnrn但是由于WSASend有可能<em>投递</em>不完整,可能第一次只<em>投递</em>出去了5字节,我们在IOCP线程中捕获到了<em>投递</em>不完整,然后<em>投递</em>剩余的数据~~rnrn那么最终的顺序是不是就变成了,一共20字节数据,前5字节是a,然后10字节的b,最后5字节为arnrn由于这种情况不好模拟,所以来问问,我分析的对吗?
IOCP_8_投递接收数据任务_WSARecv
本课程由刘远东、张立铜两位工程师将两人在企业多年积累的开发经验结合而成。从基础的网络知识开始由浅入深地讲解如何使用C++实现一套支持百万级别并发的网络通信引擎。包含:高频并发、多线程、多进程、线程池、内存池、软件硬件瓶颈、如何测试优化网络处理能力等技术知识。可以应用在Windows、Linux、Android、IOS系统上。对从事高性能网络处理的前后端开发人员有极大帮助。咨询群:648738912
IOCP_9_投递发送数据任务_WSASend
本课程由刘远东、张立铜两位工程师将两人在企业多年积累的开发经验结合而成。从基础的网络知识开始由浅入深地讲解如何使用C++实现一套支持百万级别并发的网络通信引擎。包含:高频并发、多线程、多进程、线程池、内存池、软件硬件瓶颈、如何测试优化网络处理能力等技术知识。可以应用在Windows、Linux、Android、IOS系统上。对从事高性能网络处理的前后端开发人员有极大帮助。咨询群:648738912
完成端口投递0字节WsARecv的问题
完成端口下<em>投递</em>0字节的WSARecv得到完成通知后是用重叠的WSARecv还是recv接受到达的数据?rn如果数据达到后用WSARecv接受会产生什么<em>问题</em>?rn一般都把完成端口<em>模式</em>比作快递邮件,就是你告诉快递公司有邮件了直接送到你家里,rn如果是<em>投递</em>0字节的WSARecv得话是不是相当于你告诉快递公司有邮件了打电话通知你,然后你自己再亲自去取呢?rn如果数据到达了用wSARecv接受是不是在接受数据后还会<em>投递</em>一个接受请求呢?
关于IPCP完成端口WSARecv和WSASend函数的问题
我知道怎么创建和绑定完成端口,但对WSASend,WASRecv函数不大理解。假如我的工作线程如下:rntypedef structrnrn OVERLAPPED Overlapped;rn WSABUF DataBuf;rn int OpCode;//操作<em>模式</em>代码,在重叠IO<em>投递</em>前由用户设定,0为接收,1为发送rn CHAR Buffer[DATA_BUFSIZE];rn PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;rntypedef structrnrn SOCKET Socket;rn PER_HANDLE_DATA, * LPPER_HANDLE_DATA;rnDWORD WINAPI ProcessIO(LPVOID lpParam)rnrn DWORD i;rn HANDLE CompletionPort = (HANDLE)lpParam;rn DWORD BytesTransferred, SendBytes;rn LPOVERLAPPED lpOverlapped;rn LPPER_HANDLE_DATA PerHandleData = NULL;rn LPPER_IO_OPERATION_DATA PerIoData = NULL;rn while(1)rn rnrn if(0==GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&lpOverlapped, INFINITE))rn rn return 0;rn rn PerIoData =(LPPER_IO_OPERATION_DATA)CONTAINING_RECORD(lpOverlapped, PER_IO_OPERATION_DATA,Overlapped);rn if (PerIoData->OpCode == 0x01) //发送结束操作被从IOCP队列中取出rn rn if (BytesTransferred == PerIoData->DataBuf.len) //本次传输字节数等于发送缓冲区字节数,说明传输已经全部完成rn rn DWORD Flags = 0;rn DWORD dwRecv = 0;rn ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));rn PerIoData->DataBuf.buf = PerIoData->Buffer;rn PerIoData->DataBuf.len = DATA_BUFSIZE;rn WSARecv(PerHandleData->Socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);rn continue;rn rn rn if (PerIoData->OpCode == 0x00) //接收到数据rn rn DWORD Flags = 0;rn DWORD dwRecv = 0; rn i = 0;rn PerIoData->DataBuf.len = BytesTransferred;rn ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED)); //清0为发送准备rn PerIoData->OpCode = 1; //标记<em>投递</em>的是一个发送操作rn WSASend(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &SendBytes, 0, &(PerIoData->Overlapped), NULL); rn continue;rn rn rn return 0;rnrn当我有信息接入后就会调用GetQueuedCompletionStatus,经过判断后if (PerIoData->OpCode == 0x00)运行这里面的内容,这里面有句PerIoData->OpCode = 1;这里面把这个标志设为1有什么用?后面紧接着调用WSASend()函数,是不是又会调用GetQueuedCompletionStatus,然后判断后rnif (PerIoData->OpCode == 0x01)运行这下面的内容,而这里面调用了WSARecv函数,是不是又调用GetQueuedCompletionStatus,然后再判断后运行if (PerIoData->OpCode == 0x00)下面的内容?从上面的代码很难理解WSARecv和WSASend,因为当我要发送数据的时候应该直接调用WSASend函数就行了,但PerIoData->OpCode = 1;这句话说是标记<em>投递</em>的是一个发送操作,为什么要这样?既然已经用了WSASend就能发送数据了,为什么还要投记标记,并且也看不出这个标记在哪调用的。还有就是当我要接收信息的时候直接在(PerIoData->OpCode == 0x00)里进行处理收到的数据就行了,为什么还要用WSARecv这个函数?rn我的理解是WSARecv调用这个函数时一直挂起,直到有数据来时接收,然后调用GetQueuedCompletionStatus,在 if (PerIoData->OpCode == 0x00) 里完成接收数据的处理,是不是这样的?当调用WSASend时调用GetQueuedCompletionStatus,然后在if (PerIoData->OpCode == 0x01)下处理,我理解是否正确?但这样的话把操作类型设为1 PerIoData->OpCode = 1就完全没用了。
同时send和WSASend的问题
需要将数据库的数据和向另外一个服务请求返回的结果数据发送到客户端,就需要多线程<em>同时</em>向一个客户端send或WSASend大量数据,send和WSASend之后的GetQueuedCompletionStatus都有可能返回小于发送数据量的数值,这时需要继续发送未发送完的数据,在这个间隙,就可能有另外线程发送了一小段数据到客户端,这样客户端接收到的数据是否会错乱呢?
高手请进,关于winsock2的wsarecv\wsasend问题
高手请进,关于winsock2的<em>wsarecv</em>\<em>wsasend</em><em>问题</em>rn请各位高说提供些源代码以解小弟一时之急!主要是非住塞式收发数据
wsasend发送了结构体,wsarecv接收的问题?
代码中friend1,friend4都是结构体Myfriend的变量rnrn发送端的代码:rnchar buff[100]; memcpy(buff,&friend1,sizeof(friend1)); rnint len_buf = strlen(buff); rnbuff[len+1] = '\0 ';rn rnif (SOCKET_ERROR==send(<em>socket</em>1,buff,len_buf,0))rnrn MessageBox("发送失败");rn rnrnrn接收端我不知道怎么写?大家看我这样错在哪里?rn if (SOCKET_ERROR==WSARecv(m_<em>socket</em>,&wsabuf,1,&dwread,&dwflag,&RecvOverlapped,NULL))rn rn MessageBox("接收数据失败");rn break;rn rnMyfriend friend4;rnmemset(&friend4,0,sizeof(friend4));rnmemcpy(&friend4,wsabuf,sizeof(friend4));rn最后直接异常退出了
GetQueuedCompletionStatus WSASend WSARecv绑定参数区分问题
一个<em>socket</em>与完成端口绑定,然后即可能调用了 WSARecv 又可能调用了 WSASend rn那么WSASend的参数怎么绑定给GetQueuedCompletionStatus 第三个参数的?rnWSARecv 绑定时是用了CreateIoCompletionPort((HANDLE)hSocket, m_hIOCP, (ULONG_PTR)pIoRecvContent, 0) 第三个参数绑定了iocontent ,rnWSASend 代码如下,这个代码是没有<em>问题</em>的GetQueuedCompletionStatus 能收到它的iocontent ,rn可是我没看见绑定iocontent 的语句啊,谁能回答一下?rn tryrn rn DWORD sendlen=0;rn for( DWORD _start=0; _startbuf, buf+_start, sendlen);rn sendbuf->count = (LONG)(count+1);rnrn for(i=0, ok_count=0; ioverlapped, sizeof(iocontent->overlapped));rnrn if( bcolse && i >= count -1 )rn iocontent->state = eIoBeconSendClose;rn elsern iocontent->state = eIoBeconSend;rnrn iocontent->sendbuf = sendbuf;rn iocontent->wsabuf.buf = (char *)sendbuf->buf;rn iocontent->wsabuf.len = sendlen;rnrn numbytes = 0;rnrn iocontent->sock = socks[i];rn if( (WSASend(socks[i], &iocontent->wsabuf, 1, &numbytes, 0, &iocontent->overlapped, NULL)!=SOCKET_ERROR)rn ||(ERROR_IO_PENDING==WSAGetLastError()) )rn rn ok_count++;rnrn m_sendBufLenArray.Lock();rn int sockind = m_sendBufLenArray.FindNode(socks[i]);rn if(-1==sockind) rn rn sockind = m_sendBufLenArray.NewNode(socks[i],TRUE);rn *(m_sendBufLenArray[sockind]) = 0;rn rn if(-1!=sockind)rn rn (*m_sendBufLenArray[sockind]) ++;rn rn m_sendBufLenArray.Unlock();rnrn continue;rn rnrn FreeIOContent(iocontent);rn rn InterlockedDecrement(&sendbuf->count);rn rnrn if(InterlockedDecrement(&sendbuf->count)==0)rn rn FreeSendBuf(sendbuf);rn rn rn //关闭rn if( bcolse )rn rn for ( DWORD i = 0; i
在完成例程内投递WSARecv()遇到的问题
在完成例程内,ZeroMemory(&OverLapped,sizeof(WSAOVERLAPPED));rn DataBuf.len=BufferSize;rn DataBuf.buf=Buffer;rnrn if((Error=WSARecv(AcceptSocket,&DataBuf,1,&RecvBytes,&Flags,&OverLapped, &DataCollectionClass::WorkerRoutine))==SOCKET_ERROR)rn if(WSAGetLastError()!=WSA_IO_PENDING)rn rn cout<<
WSARecv投递0字节缓冲区的问题
WSARecv<em>投递</em>一个长度为0的buf后,为什么非分页内存的大小还是会增加,另外锁定非分页内存是一个怎样的概念,求大神指导!
WSASend和WSARecv在网络慢时的问题.
在网络速度慢时,为什么.用WSARecv收WSASend所发出的数据,会减少?网络好是,可以收到正常的数据量.每次发送一般,10K数据.
对一个同一个socketwsarecv 后, 再wsasend
需要不需要,进行wsaresetevent?rnrn伪代码:rnrn//线程1rnrn//接受客户端连接后就<em>投递</em>请求rnnRet=<em>wsarecv</em>(<em>socket</em>,,,,,,,,,,,); rnrnrnrnrnrnrn//线程2rnif(nret==wsa_io_pending)rnrnrnindex=wsawatiformutipleevents.......rnrnwsareseteventrnrngetoverlappedResultrnrnprintf 打印收到的数据rnrnrn[color=#FF0000]rnrnrn<em>wsasend</em>数据到 这个<em>socket</em>rnrn[/color]rnrnrn再次用<em>wsarecv</em><em>投递</em>请求,准备接受数据rnrnrn //end ifrnrnrnrn看到有颜色的那块了嘛?rnrn <em>wsarecv</em>, <em>wsasend</em>有个参数是重叠io, 重叠io结构体中有个成员是 事件rnrn<em>wsasend</em>后,再次用<em>wsarecv</em>,会不会有 影响重叠io结构体的<em>问题</em>?rnrn比如<em>wsasend</em>影响到了重叠io结构体,那么再次<em>wsarecv</em>后,rnrn就会影响到了wsawaitformutipleevents?rnrnrnrnrnrn
异步非阻塞模式 WSASend,WSARecv等,怎么设置超时?
比如:rnWSARecv 2秒没有接受完成就关闭<em>socket</em>,rnWSASend 1秒没有发送完成就关闭<em>socket</em>。rnrn我测试一下WSASend,不管客服端接收实际完成与否,总是返回成功。rnrn怎么处理这个<em>问题</em>呢?rn谢谢。rnrn
IOCP 使用WSASend群发消息
http://download.csdn.net/my/uploads 稍加改动
iocp中如何提升WSASend发送效率?
RT.小弟最近研究<em>iocp</em>,在使用WSASend异步<em>投递</em>时,需要关联一个Overlapped结构,现在的做法是每次都new一个,然后在收到完成通知时delete,感觉效率低。我看网上的做法,一种是采用线性来发送数据,即第一次WSASend完成后才<em>投递</em>第二个,这样就共用一个overlapped结构;第二种是用内存池(对象池),但是也有人表示要实际测试,很多人自己写的内存池还不如标准库的内存分配高效;请问该如何选择呢?有没有实际测试过的方案?
IOCP在什么时机投递WSA_RECV?
一般来说WSA_SEND在什么地方<em>投递</em>都比较清楚,在需要主动SEND的时候和收到了消息需要响应时。rn但什么时候<em>投递</em>WSA_RECV呢?rnrn考虑一个客户端和一个服务端,都采用IOCP。rn客户端采用定时器定时在多个链路上发送消息到服务端(循环发送大量数据,进行性能测试用),服务端则返回响应。rnrn最开始的时候我在工作线程中GetQueuedCompletionStatus,检查到WSA_SEND完成了或者WSA_RECV完成了,就来<em>投递</em>一个新的WSA_RECV,后来发现会丢失响应。rn后来我在客户端和服务端建立连接的时候,就在每个链路上都<em>投递</em>一个WSA_RECV,然后检查到WSA_SEND完成或者WSA_RECV完成,再次<em>投递</em>一个WSA_RECV。好像也有<em>问题</em>。rn我必须在服务端Sleep一下再返回响应,才能接收正确。rn请教一下高手,一般在什么地方<em>投递</em>WSA_RECV?rnrn关于IOCP一直有一个疑问,如果服务端返回了多个响应消息,但我只<em>投递</em>一个WSA_RECV,那么是不是我只能收到一个响应?rn如果我在WSA_RECV完成后再<em>投递</em>一个新的WSA_RECV,是否可能在这个期间内丢失响应消息?rnrnif(OperationType==WSA_RECV)rnrn //do something,这个时候如果服务器发回响应,是否就丢失了?rnrn//<em>投递</em>一个新的WSA_RECV
IOCP 投递recv 请求失败
我目前在写一个服务器,有个客户端列表,客户端连接上服务器之后首先发送验证消息,如果验证成功在界面上现实某个客户端在线,现在出现这么个情况,我的服务端 开启之后,程序能够登陆,但是在程序不关闭的情况下,重启服务,当客户端再次连接之后,<em>投递</em>recv请求时候出现错误,错误代码 10057. 这个大概是什么原因??
WSARecv 不用iocp如何接收数据?
我不代码贴出来,高手帮我rnrn[code=C/C++]#include rn#include rn#pragma comment(lib,"WS2_32.lib")rnusing namespace std;rnconst int prot=9911;rnrnvoid main()rnrn WSADATA wsaData; rn SOCKET ListenSocket = INVALID_SOCKET; rn WSAStartup(MAKEWORD(2,2),&wsaData); rn ListenSocket = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,NULL,WSA_FLAG_OVERLAPPED); rn SOCKADDR_IN ServerAddr; rn ServerAddr.sin_family = AF_INET; rn ServerAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); rn ServerAddr.sin_port = htons(prot); rn bind(ListenSocket,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr)); rn listen(ListenSocket,100); rn SOCKET lSocket = INVALID_SOCKET; //临时SOCKrn SOCKADDR_IN ClientAddr; rn int addr_length=sizeof(ClientAddr); rn rn if ((lSocket = accept(ListenSocket,(SOCKADDR*)&ClientAddr, &addr_length)) == INVALID_SOCKET) exit(0)//连接失败rnrn //连接成功rnrnWSAOVERLAPPED RecvOverlapped=0;rn rn WSABUF DataBuf;rn DWORD RecvBytes, Flags;rn DataBuf.len = 145;rn DataBuf.buf = new char[145];rnrn while(1)rn rn WSARecv(lSocket, &DataBuf, 1, &RecvBytes, &Flags, &RecvOverlapped, NULL);rn rn /*怎么写啊,WSARecv这函数怎么用啊,我要用他反复的接收,不用IOCP的 那个好麻烦呀,我只是接收一个客户端*/rnrn rn system("pause");rn[/code]
WSARecv (AccetpEx连接上了,投递WSARecv 扔出一个10057错误)
WSARecv (AccetpEx连接上了,<em>投递</em>WSARecv 扔出一个10057错误)rn更加郁闷的就是,昨晚写完好好的能运行。。今天早上,不修改源码,直接运行。。然后扔错误rn还要郁闷的不是在XP 系统上,直接运行不起来~~~~~~~~~求解啊。。。
请教一个IOCP关于WSASend的变量声明问题
请教一个IOCP关于WSASend的变量声明<em>问题</em>!rn代码1如下rn[code=c]void ClientContext::PostSend ( LPBYTE lpData, UINT nSize )rn OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IOWrite);rn ULONG ulFlags = MSG_PARTIAL; rn m_WriteBuffer.Write((PBYTE)&nSize, sizeof(nSize));rn m_WriteBuffer.Write(lpData, nSize);rn m_wsaOutBuffer.buf = (char*) m_WriteBuffer.GetBuffer(); //注意:这里是成员变量rn m_wsaOutBuffer.len = m_WriteBuffer.GetBufferLen();rn int nRetVal = WSASend( m_Socket, &m_wsaOutBuffer,1,&m_wsaOutBuffer.len,ulFlags,&pOverlap->m_ol,NULL);rn[/code]rn代码2rn[code=c]void ClientContext::PostSend ( LPBYTE lpData, UINT nSize )rn OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IOWrite);rn WSABUF sndBuf;rn ULONG ulFlags = MSG_PARTIAL; rnrn m_WriteBuffer.Write((PBYTE)&nSize, sizeof(nSize));rn m_WriteBuffer.Write(lpData, nSize);rn sndBuf.buf = (char*) m_WriteBuffer.GetBuffer(); //注意:这里是局部变量rn sndBuf.len = m_WriteBuffer.GetBufferLen();rn int nRetVal = WSASend( m_Socket, &m_wsaOutBuffer,1,&m_wsaOutBuffer.len,ulFlags,&pOverlap->m_ol,NULL);rn[/code]rnrn[color=#FF0000]请问代码2中,因为WSAsend会马上返回,局部变量难道不会发生析构吗?rn<em>问题</em>2: 代码1是成员变量,WSAsend是重叠的,马上返回,如果第一次还没发送完成,那么第二次又调用了PostSend函数,此时第一次还没发送完全,m_WriteBuffer指向的数据已经发生改变,请问我的分析对吗?rn正确的该如何写?[/color]rnrn
完成端口 WSASend 后 必须要 WSARecv吗? WSARecv-〉WSASend
如题:rn形如:rnvoid funcSend()rnrn...rn WSASend();rn...rnrnvoid funcRecv()rnrn...rnWSARecv(...);rn...rnrnvoid test()rnrn void funcRecv();rn void funcSend();rn///////rn如果不<em>投递</em>WSARecv,GetQueuedCompletionStatus 将不会收到读请求的结果。rn void funcRecv();rnrnrn还有,客户端向服务端发送数据,GetQueuedCompletionStatus 传递的长度跟 数据标示的长度不一致。
关于异步IO函数,WSASend和WSARecv的疑问?
如题:我看了他们俩的缓冲区都是char类型的, 但是如果我要发送和接收byte类型的数据怎么办呢?比如说收发文件吧。难道得先转换成char进行发送, 然后接收后在转换成byte吗?
Socket中的IOCP 技术介绍
关于Socket通讯中呗神化的IOCP技术的介绍
如何取消或者结束服务器端已经投递的WSARecv投递
<em>socket</em>上<em>投递</em>了WSARecv,那么如何取消该<em>投递</em>或者结束该<em>投递</em>?也就是说:如果客户端不发送数据的话,是否可以在服务器端怎么处理一下,让WSARecv接收到一个数据包,从而结束该<em>投递</em>;
socket中wsaeventselect,iocp
IOCP源代码,里面还包括了其他的几个i/o模型。期待你的下载,进行学习交流
关于delphi的iocp的WSARecv调用问题请教
最近在学习IOCP,在网上看到 WSARecv的调用代码为(WSARecv(Acceptsc, @(PerIoData.DataBuf), 1, @RecvBytes, @Flags,@(PerIoData.Overlapped), nil),这个代码里的RecvBytes和Flags这两个变量没有搞懂是哪里来的,是delphi里事先定义好的吗,还是winsock2里定义了的,还是需要自己在程序定义,如果是需要自己定义,要怎么做?
请教IOCP投递问题,此问题很是奇怪
RT 此<em>问题</em>很是奇怪的很。rn看了很久IOCP的文章了。rn但是对于<em>投递</em>操作,网络上似乎分为两大派系,rn下面我分别说一下:rnrn[color=#FF0000]第一种<em>投递</em>方式:[/color]rn是在IOCP线程池 外部直接调用WSASend或者WSARecive?而PostQueuedCompletionStatus只是被用来需要停止IOCP工作线程的时候调用一下(我自己,感觉这个函数是不是被用得鸡肋了?)rn然后再在IOCP 工作线程里面通过rn调用GetQueuedCompletionStatus 得到结果的状态通知。rnrn[color=#FF0000]第二种<em>投递</em>方式:[/color]rn在IOCP工作线程外部只调用 PostQueuedCompletionStatus 来进行任何<em>投递</em>操作。rnrn然后再调用 GetQueuedCompletionStatus 得到Post的<em>投递</em>,然后判断<em>投递</em>的类型,比如是Send数据,rn那就调用WSASend来发送一下。。。rn而发送的成功与否的结果通知还是通过GetQueuedCompletionStatus这个在下一次的时候得到?rnrnrnrn[color=#FF0000]那么,这两种方法,到底哪一种是正确的方法呢?肯定只有一种是正确的而且最合理额吧?[/color]rn————<em>问题</em>分割线—————————————————————————————<em>问题</em>分割线————rn还有 IOCP 比如 我要发送 一个2KB的数据,是不是只要在外部<em>投递</em>一次就好了?rnrn这里的外部<em>投递</em>是指在IOCP工作线程之外,进行一个PostQueuedCompletionStatus 函数的调用。rnrn然后在工作线程里面 是不是受到<em>投递</em>请求只要调用一次WSASend,一次性发送然后等待结果就行了?但是我缓冲区只设置了1kB。。。这个要怎么弄,自己处理发送两次吗?rnrn————<em>问题</em>分割线—————————————————————————————<em>问题</em>分割线————rn于此<em>同时</em>,我还发现另外一个<em>问题</em>。rn很多人写IOCP都是一个个<em>投递</em>,这样是不是一种错误的做法?rnrnIOCP的N次<em>投递</em>(重叠<em>投递</em>),一次处理,不就是IOCP的最大的好处吗,rn如果不重叠了,IOCP就不能够将多个操作合并为一个,而这就会失去IOCP很大的IO并发处理的意义,是这样的吧?
WSARecv()同时发生Overlapped IO投递和立即返回
读<em>投递</em>操作如下(只看代码结构):rnrn[code=C/C++]rnDWORD PostRead(PerIoOpData* pIoOpData, PerHandleCpKey* pCpKey)rnrn // 省略一堆变量声明rnrn // 使用 WSARecv() <em>投递</em> Overlapped IO 接收操作rnrn dwErr = WSARecv(pCpKey->sAcpt, &(pIoOpData->wsabuf), 1, &bytesRecvd, &flag,rn &(pIoOpData->ol), NULL);rnrn if ( SOCKET_ERROR == dwErr )rn rn dwErr = WSAGetLastError();rn // 这里为 WSA_IO_PENDING,说明<em>投递</em> Overlapped IO 成功rn rn elsern rn // WSARecv() 操作立即完成,此时 bytesRecvd 中保存接收的字节数rn _ftprintf(stderr, _T("WSARecv() operation completes immediately\n"));rn ProcessRead(pIoOpData, pCpKey, bytesRecvd);rn rnrn dwErr = ERROR_SUCCESS;rnrnRET:rn return dwErr;rnrn[/code]rnrnIOCP + 线程池 方式管理交叠IO。rnrn用VC跟踪时,第一个发起<em>投递</em>的线程A,走到这个函数中,调用WSARecv(),然后返回 dwErr = 0,说明“读操作”立即完成,然后执行 _ftprintf() 那句,_ftprintf()还没执行完时,池中的另外一个 worker 线程B 激活了(即GetQueuedCompletionStatus() release 掉了)(我在 worker 线程历程中下了断点,所以能看见这种情况)。rnrn然后就走 线程B 的执行,竟然是读操作的完成通知,那一定是 线程 A 的 WSARecv() 的交叠IO <em>投递</em>成功了。rnrn然后 线程B 先打印出(我的接收后处理是打印)接收到的数据,然后回到循环中的 GetQueuedCompletionStatus() 阻塞,等待下次完成通知。rnrn最后 调度到了 线程A,_ftprintf() 走完,然后又打印一遍 A 时代立即完成时,接收到的数据,和 B 的一样。rnrn这样,只发送了一份数据,在服务端却处理了两次。rnrn我的情况是 A 中接收的数据,是已经完全接收完了,不是说:只接收到一部分(通过立即返回表现),没接收到的数据,变成 交叠 IO <em>投递</em>到 IOCP 上了(要是这种情况倒是很容易想通)。rnrn我的数据两次(一次,WSARecv()立即返回得到的;另一次,IOCP的交叠IO完成通知得到的)完全一样。rnrn原本以为立即返回的IO,是不会<em>投递</em>未决的交叠IO的,没想到……rnrn大家在开发高并发服务时,有遇到这种情况吗,是怎么管理这种 “[color=#FF0000]立即返回 + Overlapped IO<em>投递</em>[/color]” <em>同时</em>出现的<em>问题</em>呢?rnrnPS.rnrnA->B->A的调度顺序大概是因为那个 printf(),它与终端间的 IO 引发了 pending,就切到 B 了
请教在异步模式下WSASend的问题
<em>问题</em>是这样的:我的服务器要向客户端发送一个自定义的结构体,例如:rnstruct myStructrnrn int ID;rn char name[30];rn;rn在异步<em>模式</em>下(MFC),在服务器端我调用WSASend(...)来发送这个结构体:rn myStruct stru;rn stru.ID = 10;rn stru.name = "XXX";rn rn WSABUF data;rn int len = sizeof(myStruct); rn data.len = len;rn data.buf =(char*)&stru;rn最后调用 WSASend发送。rnrn在客户端,使用WSARecv接收。可是在客户端接收的数据是错误的,还出现了内存访问错误的情况。而在WIN32控制台环境下,我使用同步方式编写的程序就能发送成功。请问这是什么原因啊?怎么解决这个<em>问题</em>?请各位大侠不吝赐教。谢谢!rn
为什么WSASend了但是WSARecv没有收到?
客户端WSASend已经弹出发送成功的提示了,但是在服务器用select测试却是不可读,没有收到信息,必须重新发送一次连接一次<em>socket</em>才能收到?rn请问为什么?
请教WSASend(),WSARecv两个函数参数的含义
服务器端WSASend(),WSARecv两个函数的各个参数分别的含义是什么?第一个参数<em>socket</em>分别指服务器端的<em>socket</em>还是另一端的<em>socket</em>?send(),Recv呢?还有个<em>问题</em>,为什么完成端口接受客户端连接请求后,还要把Accept函数返回的那个<em>socket</em>与完成端口连接起来?谢谢指教!
请问高手: 关于WSASend和WSArecv的实现细节
当把<em>socket</em>绑定到一个IOCP上的时候, 调用WSASend send数据, 如果返回SOCKET_ERROR, error_code = IO_PENDING, 那么我们可以去IOCP上等待结果, 结果可能成功, 可能失败, 即使成功也可能只send了部分数据. 但是如果WSASend如果返回0, 代表数据被copy到<em>socket</em> snd buffer里面去了? 还是已经送出去了? 这种情况下我们也必须去IOCP守候一个完成事件, 虽然事件是瞬间达到的, 但这之间有一次线程切换, 这不是一种低效的做法吗? 如果确实瞬间发送成功了, 有没有办法压制这次WSASend的完成事件? 毕竟尽可能快地<em>投递</em>请求可以提高一些效率.rnrn关于WSARecv同理, 当通过WSARecv<em>投递</em>recv请求的时候, 返回0, 代表数据已经收到了? 还是必须再去IOCP上等待这次完成事件? 我做了一些测试, 倒没有发现WSARecv返回0的情况, WSASend的情况是很多的, 我没有调整<em>socket</em>的缺省的snd buffer和recv buffer, 应该是8192个bytes的吧.rnrn请高手帮忙解答下, 不胜感激.rn
关于 WSASend/WSARecv 和重叠IO的几个问题?
书上:rn[Quote= Overlapped I/O事件通知模型:] rn 重叠I/O的事件通知方法要求将Win32事件对象与WSAOVERLAPPED结构关联在一起。若使用一个WSAOVERLAPPED结构,发出像WSASend和WSARecv这样的I/O调用,它们会立即返回。rn 通常,这些I/O调用会以失败告终,返回SOCKET_ERROR 。rn 一个重叠请求操作最终完成之后,在事件通知方法中,Winsock会更改与一个WSAOVERLAPPED结构对应的一个事件对象的事件传信状态,将其从“未传信”变成“已传信”。发现一次重叠请求完成之后,接着需要调用WSAGetOverlappedResult(取得重叠结构)函数,判断该重叠调用到底是成功,还是失败。rn ……rn重叠I / O编程步骤为:rn1) 创建一个套接字,开始在指定的端口上监听连接请求。rn2) 接受一个进入的连接请求。rn3) 为接受的套接字新建一个WSAOVERLAPPED结构,并为该结构分配一个事件对象句柄。也将事件对象句柄分配给一个事件数组,以便稍后由WSAWaitForMultipleEvents函数使用。rn4) 在套接字上<em>投递</em>一个异步WSARecv请求,指定参数为WSAOVERLAPPED结构。注意函数通常会以失败告终,返回SOCKET_ERROR错误状态WSA_IO_PENDING(I/O操作尚未完成)。rn5) 使用步骤3 )的事件数组,调用WSAWaitForMultipleEvents函数,并等待与重叠调用关联在一起的事件进入“已传信”状态(即,等待那个事件的“触发”)。rn6) WSAWaitForMultipleEvents函数完成后,针对事件数组,调用WSAResetEvent(重设事件)函数,复位事件对象,并对完成的重叠请求进行处理。rn7) 使用WSAGetOverlappedResult函数,判断重叠调用的返回状态是什么。rn8) 在套接字上<em>投递</em>另一个重叠WSARecv请求。rn9) 重复步骤5 ) ~ 8 )。rnrn[/Quote]rnrn1. 立即返回,这个“立即” 是什么含义?rn2. 这些I/O调用为什么会通常以失败告终?rn3. 既然WSASend的返回值可以判断是否发送成功,那这里为什么还要用WSAWaitForMultipleEvents 这么麻烦 ?rn4. 据说有发送了一半的情况?是这样吗? 如果有这种情况的话,这算是成功还是失败?接下来怎么办?
iocp socket 安全沙箱问题
本人最近要用vc写个<em>iocp</em>服务器和前端flash配合,但一直存在沙箱<em>问题</em>。网上查了不少资料,都说服务器接受到 “\0”时 就返回一个安全策略文件,rn但奇怪的是,如果服务端是同步<em>模式</em>就可行rn采用<em>iocp</em>异步机制的时候 ,信息虽然发出去了 ,但还是存在沙箱<em>问题</em> rn本地测试没<em>问题</em>,放网上就有安全沙箱<em>问题</em>rn关键代码如下 望高手指点一二rnrn//接受到安全请求时发送策略文件 这里策略文件发送成功了rnmessage = SI->DataBuf.buf;rnint m;rnm = message.Find("");rnif(m >= 0)rnrn CString xml = "";rnxml = xml + "";rnxml = xml + "";rnxml = xml + "\0";rnrnsprintf(SI->DataBuf.buf,"%s",xml);rnSI->DataBuf.len = strlen(SI->DataBuf.buf);rnSI->IoType = IOSEND; rnif (WSASend(SI->Socket, &SI->DataBuf, 1, &Bytes, Flags, &SI->Overlapped, NULL) == SOCKET_ERROR)rnrn if(WSAGetLastError() != WSA_IO_PENDING)rn rn close<em>socket</em>(SI->Socket); rn rnrnrn// 但是发送后 代码跳到这里出错了 BytesTransferred 为0 不知道怎么回事。 rnif (GetQueuedCompletionStatus(hCompPort, &BytesTransferred, (LPDWORD)&SI, &Overlapped, INFINITE))rnrn if (0 == BytesTransferred && IOQUIT != SI->IoType)rn rn //退出操作rnrn懂的人指点下 谢谢
一个IOCP socket问题
IOCP + acceptex + <em>socket</em>重用。rnrn连接客户端完成后,重设<em>socket</em> , 重新<em>投递</em>,当新连接请求时,<em>socket</em> 是最后<em>投递</em>的那个。rn比如<em>socket</em> 最开始先后依次<em>投递</em>3个,编号是 111,222,333. rn当连接请求来到时,首先连接的是333,用完后重设<em>投递</em>333,当又一个新连接请求来到时,连接的还是333,rn开始那两个111,222根本就没用了。rnrn那是不是IOCP其实只需要一个客服<em>socket</em>就够了?rn即使为了应付<em>同时</em>多个请求,开几个线程就只需要几个用于接收客户的<em>socket</em> 就行了吗?rnrn谢谢。rn
IOCP, socket重用的问题
调用 DisconnectEx 这个函数断开 <em>socket</em> 后,又怎么处理呢?rnrn有的说用 CreateIoCompletionPort 这个函数重新绑定到完成端口,rn也有说需要用 AcceptEx 重新<em>投递</em>,rnrn到底怎么处理?rn谢谢前辈。rnrn
Winsock重叠操作投递WSARecv 错误
我这里遇到一个<em>问题</em>,我通过异步事件 WSAEventSelect(m_SerStatus.sockListen, m_wsaEventAccept, FD_ACCEPT|FD_CLOSE);rn在一个线程中来accept一个客户端 rn<em>socket</em> = accept(pServer->m_SerStatus.sockListen, (struct sockaddr *)&addr_in, &iLen);rn成功后立即<em>投递</em>第一个WSARecv重叠操作rnif(WSARecv( <em>socket</em>, rn &pServer->m_OverLappedExRcv[iIndex].wsaBuf, rn 1, rn &dwRecvBytes, rn &dwFlags, rn &pServer->m_OverLappedExRcv[iIndex].wsaOverlapped, rn CompletionRoutine_ReceiveSock) == SOCKET_ERROR) rn iErr = WSAGetLastError(); //rn可是这里每次都是失败,错误码:0x273d 也就是 WSAEOPNOTSUPP 错误,"MSG_OOB was specified, but the <em>socket</em> is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this <em>socket</em>, or the <em>socket</em> is unidirectional and supports only send operations.".rn这个错误怎么解决呢?rn
WSASend投递,WSAGetLastError()得到错误代码 6
使用完成端口来编写的一个程序,使用WSASend来<em>投递</em>数据,返回值表示已经成功了。rn在完成端口的服务线程中,GetQueuedCompletionStatus结果为False,使用WSAGetLastError查到的错误是6,搜了一下,其中有个回答是OVERLAPPED 里的hEvent无效,但我已经用WSACreateEvent赋值了。rn[code=Delphi(Pascal)]rn str := Edit1.Text + chr($D);rnrn new(PerIoData);rn for k:= 1 to Length(str) dorn PerIoData.Buffer[k-1] := str[k];rnrn ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));rn PerIoData.Overlapped.hEvent := WSACreateEvent();rnrn PerIoData.DataBuf.buf := @PerIoData.Buffer;rn PerIoData.DataBuf.len := DATA_BUFSIZE;//length(str);rn PerIoData.IOType := ioWrite;rnrnrn if (WSASend(m_<em>socket</em>, @(PerIoData.DataBuf), 1, @SendBytes, 0, @(PerIoData.Overlapped), nil) = SOCKET_ERROR) thenrn beginrn if (WSAGetLastError() <> ERROR_IO_PENDING) thenrn beginrn self.Memo1.Lines.Add('WSASend() failed with error');rn end;rn end;rnrn[/code]rnrnLPPER_IO_OPERATION_DATA = ^ PER_IO_OPERATION_DATA ;rn PER_IO_OPERATION_DATA = packed recordrn Overlapped: WSAOVERLAPPED;rn DataBuf: TWSABUF;rn Buffer: array [0..DATA_BUFSIZE] of CHAR;rn BytesSEND: DWORD;rn BytesRECV: DWORD;rnrn IOType :TIOType;rn end;
WSAAccept WSARecv WSASend 后,再也收不到 OP_IORead 了?
完成端口, 服务端 WSAAccept 客户端 后,<em>投递</em> WSARecv, 收到 OP_IORead ,然后再 WSASend ,再也收不到 OP_IORead 了?rn关键代码:rn[code=C/C++]rnDWORD WINAPI ServerWorkerThread( LPVOID pData)rnrn CListenSocket* pListen = (CListenSocket*) pData;rn DWORD BytesTransferred; rn LPWSAOVERLAPPED lpOverlapped = NULL;rn PPER_HANDLE_DATA lpPerHandleData = NULL;rn PPER_IO_DATA lpPerIOData = NULL; rn DWORD SendBytes, RecvBytes;rn DWORD Flags;rn int rc;rn BOOL bRun = TRUE;rn BOOL bRst = FALSE;rn while( bRun )rn rn bRst = GetQueuedCompletionStatus( pListen->m_hIOCP, &BytesTransferred,rn (LPDWORD)&lpPerHandleData, (LPOVERLAPPED *)&lpPerIOData, rn INFINITE);rn if ( bRst == FALSE )rn rn if ( lpPerIOData == NULL)rn rn AfxTrace( "aaa GetQueuedCompletionStatus failed with unknown error ????????? \n");rn return -1;rn rn rc = GetLastError(); rn AfxTrace( "bbb GetQueuedCompletionStatus failed with error %d\n", rc);rn CallBackClntRemove( lpPerHandleData->hSocket);rn continue;rn rn if(BytesTransferred == 0 )rn rn rc = GetLastError(); rn AfxTrace( "ccc GetQueuedCompletionStatus failed with error %d\n", rc);rn CallBackClntRemove( lpPerHandleData->hSocket );rn continue;rn rnrn switch(lpPerIOData->opType)rn rn case OP_IORead: rn lpPerIOData->nDataF = BytesTransferred;rn CallBackRcvCltData( lpPerHandleData, lpPerIOData);rn break;rn case OP_IOWrite:rn lpPerIOData->nDataF = BytesTransferred;rn CallBackWriteData( lpPerHandleData, lpPerIOData);rn break;rn case OP_IOCLNTCLOSE:rn CallBackClntRemove( lpPerHandleData->dwIP);rn break;rn case OP_IOCLOSE:rn AfxTrace("case OP_IOCLOSE:");rn bRun = FALSE;rn break;rn default:rn rn AfxTrace( "xxxxxxxxxxxxxx err ");rn rn break;rn rn rn return 0;rnrnrnint CClientSocket::WSARecvFunc()rnrn //start receive ... rn int nRst = SOCKET_ERROR;rn EnterCriticalSection( &m_sPerHandleData.rCriSec);rn //if ( m_sPerHandleData.hSocket != INVALID_SOCKET)rn rn DWORD Flags = 0;rn DWORD nRecvBytes =0;rn m_sPerIODataR.opType = OP_IORead;rn m_sPerIODataR.bufData.len = MAX_PACKSIZE;rn ZeroMemory(&(m_sPerIODataR.ol), sizeof(OVERLAPPED));rn if (WSARecv( m_sPerHandleData.hSocket, &(m_sPerIODataR.bufData), 1, &nRecvBytes, &Flags,rn &(m_sPerIODataR.ol), NULL) == SOCKET_ERROR)rn rn if (WSAGetLastError() != ERROR_IO_PENDING)rn rn AfxTrace( "WSARecv() failed with error %d \n", WSAGetLastError());rn nRst = SOCKET_ERROR;rn goto labelRetn;rn rn rn nRst = nRecvBytes;rn rnlabelRetn:rn LeaveCriticalSection( &m_sPerHandleData.rCriSec);rn return nRst;rnrnrnint CClientSocket::WSASendFunc( BYTE* lpData, int nLen)rnrn AfxTrace( "WSASendFunc \n");rn int nRst = SOCKET_ERROR;rn EnterCriticalSection( &m_sPerHandleData.sCriSec);rn //if ( m_sPerHandleData.hSocket != INVALID_SOCKET)rn rn DWORD nSendBytes;rn m_sPerIODataS.opType = OP_IOWrite;rn //m_sPerIODataS.bufData.len = m_sPerIODataS.nDataR;//MAX_PACKSIZE;rn ZeroMemory(&(m_sPerIODataS.ol), sizeof(OVERLAPPED));rn WaitForSingleObject( m_sPerHandleData.sEvent, INFINITE);rn int nLeftData;rn int nSendData;rn nSendData = 0;rn nLeftData = nLen+4;rn *(DWORD*)(&m_sPerIODataS.bufData.buf[0]) = LEN_DW + nLen;rn nSendData += 4;rn nLeftData -= 4;rn //first timesrn if ( nLeftData 0)rn rn WaitForSingleObject( m_sPerHandleData.sEvent, INFINITE);rn ZeroMemory(&(m_sPerIODataS.ol), sizeof(OVERLAPPED));rn if ( (nLeftData ) , m_sPerHandleData.dwIP, WSAGetLastError());rn nRst = SOCKET_ERROR;rn goto labelRetn;rn rn rn ResetEvent( m_sPerHandleData.sEvent);rn rn nRst = nSendBytes;rn rnlabelRetn:rn LeaveCriticalSection( &m_sPerHandleData.sCriSec);rn return nRst;rnrn[/code]
完成端口,投递第一个WSARecv时出错
如果<em>投递</em>第一个WSARecv时出现的不是ERROR_IO_PENDING,是否说明不能正常激活完成端口进行运作?rn经过bind,listen,WSAAccept之后,<em>投递</em>了第一个WSARecv激活完成端口,可总是出现10045错误:rnfor(;;)rn rn SOCKADDR saRemote;rn int RemoteLen = sizeof(saRemote); rnrn if((Accept = WSAAccept(Listen, (SOCKADDR *)&saRemote, &RemoteLen, NULL, NULL))==SOCKET_ERROR)rn rn /*rn * error occurs.rn */rn MYTRACE(TEXT("Error occurs while accept the connection.\n"));rn return;rn rnrn if((PerHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA)))==NULL)rn rn /*rn * error occurs.rn */rn MYTRACE(TEXT("Error occurs while alloc memory for PerHandleData.\n"));rn return;rn rn PerHandleData->Socket = Accept;rn memcpy(&PerHandleData->ClientAddr, &saRemote, RemoteLen);rnrn if(CreateIoCompletionPort((HANDLE)Accept, CompletionPort, (DWORD)PerHandleData, 0)==NULL)rn rn /*rn * error occurs.rn */rn MYTRACE(TEXT("Error occurs while creating I/O completion port.\n"));rn return;rn rnrn if((PerIoData=(LPPER_IO_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_DATA)))==NULL)rn rn /*rn * error occurs while allocating memory for PerIoData.rn */rn MYTRACE(TEXT("Error occurs while allocating memory for PerIoData.\n"));rn return;rn rnrn ZeroMemory(&(PerIoData->Overlapped), sizeof(WSAOVERLAPPED));rn PerIoData->DataBuf.buf = PerIoData->Buffer;rn PerIoData->DataBuf.len = DATA_BUFSIZE;rn rn if(WSARecv(Accept, &(PerIoData->DataBuf), 1, &dwBytes, &dwFlags, &(PerIoData->Overlapped), NULL)==SOCKET_ERROR)rn rn if(WSAGetLastError()!=ERROR_IO_PENDING)rn rn sprintf(szDebugString, "%d\n", WSAGetLastError());rn MYTRACE(TEXT("Errors not on I/O pending.BAD LUCK!! \n"));rn MYTRACE(TEXT(szDebugString));rn //就是总是执行到这里rn return;rn rn rn rn //for(;;)
求SOCKET wsarecv 使用例子
<em>问题</em> 如上rn客户端用socoket send 发送数据,并用<em>wsarecv</em>接收数据rnrn希望rn用C++编写,别的语言也可以rn也可以单独联系我 qq 15584598
[IOCP]WSARecv投递问题,有没有可能一次只收了1个字节?如何确定长度?
首先,WSARecv和WSASend一样,都有可能需要<em>投递</em>多次才能完成,rn但<em>问题</em>是,WSARecv怎么确定要收的包有多长??rn如果包的长度就写在包的起始字节的话,假如这个长度数据用的是int类型,那假如一次只接收了1个字节怎么办???
WSAGetOverlappedResult获得是字符串长度是wsasend还是wsarecv投递的操作?
在重叠IO模型中:rnWSAGetOverlappedResult可以获得<em>wsasend</em>所<em>投递</em>的字符串长度,当然WSAGetOverlappedResult也可以获得<em>wsarecv</em>所<em>投递</em>的字符串长度;rn如果我<em>同时</em><em>投递</em><em>wsasend</em>和<em>wsarecv</em>,那么WSAGetOverlappedResult获得<em>投递</em>结果中的字符串长度是哪一个<em>投递</em>操作?
[完成端口]是否WSASend/WSARecv投递的内存块必须要用 VirtualAlloc 等来分配?
MSDN 好象 WriteFile 提到了要用 VirtualAlloc,WSASend/WSARecv 则没有提到
IOCP在windows2003服务中运行,accept投递失败问题
<em>问题</em>描述:rn以控制台方式运行程序没有<em>问题</em>,windowsxp,2003及2008都正常;rnrn但如果以windows服务方式运行,win7及windows2008正常;rn在xp 及 2003上运行时异常,客户端无法连接server,通过log发现IOCP在完成<em>投递</em>accept后,GetQueuedCompletionStatus会返回false,WSAGetError 显示183错误,导致无法接收连接。rnm_lpfnAcceptEx方法有什么限制吗?
如何知道WSAWaitForMultipleEvents返回的事件信号是wsarecv还是wsasend投递的操作?
如题;
MFC中怎么用WSASend、WSARecv收发数据
MFC中怎么用WSASend、WSARecv收发数据.比如:用WSASend发送一个数据包到服务器,服务器返回一个数据包,使用WSARecv接收,然后再根据收到的内容在发送。MFC中怎么实现这一工程,请高人解答,不甚感激。有代码最好。
完成端口中服务端只能用WSASend和WSARecv吗?
在重叠I/O中用WSARecv,在工作者线程处理时用send()可以吗?
IOCP中 DisconnectEx函数重用SOCKET的问题
如题,不知有哪位朋友,有DisconnectEx函数的使用经验!rnrn资料中说,在调用DisConnectEx函数之前,如果存在未决的IO请求,DisConnectEx不返回或者说等不到完成事件。rnrn在我的程序中,AcceptEx函数接受客户端连接,通过定时检查SO_CONNECT_TIME选项,对连接成功未在指定时间发送数据的客户端执行断开操作。<em>同时</em>使用CancleIO取消IO请求,并调用DisconnectEx,客户端是成功断开了,但我收不到DisConnectEx的完成事件。rn在客户端主动关闭的情况下,服务端调用DisConnectEx可以收到完成事件,并可重用SOCKET句柄。rnrn哪位大侠可以指点指点我
IOCP wsarecv调用等不到完成信息
我是用WSASynSelect来得到有连接请求,然后左右<em>socket</em>都申请必要的内存并绑定到完成端口上.rnrnrn switch(WSAGETSELECTEVENT(lParam))rn rn case FD_ACCEPT:rn rn if ((<em>socket</em>Accept=WSAAccept(wParam,NULL,NULL,NULL,0)) == INVALID_SOCKET)rn rn break;rn rn rn <em>socket</em>Server=g_ThreadPool.CreateServerSocket( \rn g_ThreadPool.m_MapInfo[wParam].DestIP, g_ThreadPool.m_MapInfo[wParam].DestPort); rn if (INVALID_SOCKET==<em>socket</em>Server)rn rnrn close<em>socket</em>(<em>socket</em>Accept);rn <em>socket</em>Accept=INVALID_SOCKET;rn break;rn rnrn pPerSocketContextClient=g_ThreadPool.UpdateCompletionPort(<em>socket</em>Accept,<em>socket</em>Server,IoRead,true);rn if (NULL==pPerSocketContextClient)rn rn break;rn rnrn pPerSocketContextServer=g_ThreadPool.UpdateCompletionPort(<em>socket</em>Server,<em>socket</em>Accept,IoRead,true);rn if (NULL==pPerSocketContextServer)rn rn break;rn rn rn nRet=WSARecv(<em>socket</em>Accept,&(pPerSocketContextClient->pPerIoContext->wsabuf),1,&dwRecvNumBytes, \rn &dwFlag,&(pPerSocketContextClient->pPerIoContext->OverLapped),NULL);rn if ((SOCKET_ERROR==nRet) && (ERROR_IO_PENDING!=WSAGetLastError()))rn rn g_ThreadPool.FreeAndCloseSocket(pPerSocketContextClient);rn break;rn rnrn nRet2=WSARecv(<em>socket</em>Server,&(pPerSocketContextServer->pPerIoContext->wsabuf),1,&dwRecvNumBytes2, \rn &dwFlag2,&(pPerSocketContextServer->pPerIoContext->OverLapped),NULL);rn if ((SOCKET_ERROR==nRet2) && (ERROR_IO_PENDING!=WSAGetLastError()))rn rn g_ThreadPool.FreeAndCloseSocket(pPerSocketContextServer);rn break;rn rn break;
Voronoi Diagram下载
介绍Voronoi Diagram的一本好书。pdf 相关下载链接:[url=//download.csdn.net/download/yemaoustc/3288736?utm_source=bbsseo]//download.csdn.net/download/yemaoustc/3288736?utm_source=bbsseo[/url]
STC89s52单片机最小系统可用原理图下载
这是STC89s52的单片机的最小系统原理图,测试可用,属于实验板原理图。采用电源和USB两种供电模式,同时加上了串口。适合学习单片机基础的入门 相关下载链接:[url=//download.csdn.net/download/zhanyunzhi1987/3365028?utm_source=bbsseo]//download.csdn.net/download/zhanyunzhi1987/3365028?utm_source=bbsseo[/url]
室内智能机器人的控制系统下载
智能机器人的设计论文,关于智能系统控制的研究 相关下载链接:[url=//download.csdn.net/download/lxh223/4085225?utm_source=bbsseo]//download.csdn.net/download/lxh223/4085225?utm_source=bbsseo[/url]
相关热词 c# xml的遍历循环 c# 取 查看源码没有的 c#解决高并发 委托 c#日期转化为字符串 c# 显示问号 c# 字典对象池 c#5.0 安装程序 c# 分页算法 c# gmail 发邮件 c# 多层文件
我们是很有底线的