1.Overlapped IO模型:
在处理线程中
①Wait ForMultipleEventObjects
②调用GetOverlappedResult对①关联的SOCKET进行结果验证
If the WSAGetOverlappedResult function succeeds, the return value isTRUE. This means that your overlapped operation has completed successfully and that the value pointed to bylpcbTransfer has been updated. If the return value isFALSE, one of the following statements is true:
-
The overlapped I/O operation is still pending (as we previously described).
-
The overlapped operation completed, but with errors.
-
The overlapped operation's completion status could not be determined because of errors in one or more of the parameters supplied toWSAGetOverlappedResult.
Upon failure, the value pointed to by lpcbTransfer will not be updated, and your application should call the WSAGetLastError function to determine the cause of the failure.
③WSARecv/WSASend 通常会返回SOCKET_ERROR,WSAGetLastError()返回WSA_IO_PENDING,此时表示正在处理中
2.在自定义WSAOVERLAPPED结构时,常定义一个char buffer[size], 和一个WSABUF wsaBuffer.开始以为是重复定义缓冲区,但WSABUF结构图里面是一个长度和一个指针,所以必须另外另一个缓冲区以供其使用
3.Before continuing, there is one other important aspect about Windows completion ports that needs to be stressed. All overlapped operations are guaranteed to be executed in the order that the application issued them. However, the completion notifications returned from a completion port are not guaranteed to be in that same order
4.There are no limitations to the number of sockets that may be associated with a completion port 。。。日啊。。一个IOCP端口可以和任意多个SOCKET关联。。
5.
Function Name | Description |
WSAAccept and accept | The application has not received a connection request. Call again to check for a connection. |
closesocket | In most cases, this means that setsockopt was called with theSO_LINGER option and a nonzero timeout was set. |
WSAConnect and connect | The connection is initiated. Call again to check for completion. |
WSARecv, recv, WSARecvFrom, andrecvfrom | No data has been received. Check again later. |
WSASend, send, WSASendTo, andsendto | No buffer space available for outgoing data. Try again later. |
6.IOCP的一些细节问题:
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
SOCKET sock = WSASOCKET(...OVERLAPPED);
这两种方式都是可以的
WSARecv(accepsock, &pOverlapped->wsabuf, 1, &bytesRead, &dwFlag, &pOverlapped->ol, NULL);
dwFlag即使不想要,也不能填NULL,否则出错
MYOVERLAPPED *pOverlapped = new MYOVERLAPPED;
memset( pOverlapped, 0, sizeof(MYOVERLAPPED) );
pOverlapped->type = IO_READ;
pOverlapped->wsabuf.buf = pOverlapped->buffer;
pOverlapped->wsabuf.len = 1024;
pOverlapped->ol.hEvent = WSACreateEvent();
DWORD dwFlag = 0;
DWORD bytesRead = 0;
int err = WSARecv(accepsock, &pOverlapped->wsabuf, 1, &bytesRead, &dwFlag, &pOverlapped->ol, NULL);
不能在WSARecv后就delete pOverlapped
必须在线程函数接收到数据之后才能回收内存
MYOVERLAPPED *pOverlapped = RECORDING_CONTAIN(); 注意,是MYOVERLAPPED 指针
delete pOverlapped;
hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 2); //注意第一个参数不能使NULL
第二次绑定时最后一个参数可以使0
7.
ioctlsocket只是用来设置套接字模型的(阻塞/非阻塞)
send返回成功并不代表发送成功,对方关闭连接后发送还是会成功的,第二次发送才会失败