我用的是AcceptEx,为了调试,我只投递了一个AcceptEx,然后我就在GetQueuedCompletionStatus处等待完成,当客户连接了并发送了数据,GetQueuedCompletionStatus就返回,该处返回后代码如下:
b = GetQueuedCompletionStatus(dlg->CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleKey, (LPOVERLAPPED *) &PerIoData, INFINITE);
switch(PerIoData->IoOptType)
{
case IO_ACCEPT:
//将连接的套接字与完成端口关联
PerHandleKey = (LPPER_HANDLE_KEY) GlobalAlloc(GPTR, sizeof(PER_HANDLE_KEY));
PerHandleKey->sClient = PerIoData->sClient;
pack = *((NetPacket*)(PerIoData->DataBuf.buf)); //分析数据包
switch(pack.opt)
{
case 12:
AfxMessageBox(pack.userData);
pack.opt = 20;
strcpy(pack.userData,"返回的数据!");
break;
}
PerIoData->IoOptType = IO_SEND;
PerIoData->DataBuf.buf = (char*)&(pack);
PerIoData->DataBuf.len = sizeof(pack);
result = WSASend(PerHandleKey->sClient, &(PerIoData->DataBuf), 1, &SendBytes, 0,&(PerIoData->Overlapped), NULL);
if (result == SOCKET_ERROR && WSAGetLastError() != ERROR_IO_PENDING)
{
return ;
}
就是最后这儿返回了0,请大家多指教,谢谢!
7 个解决方案
#1
你的socket句柄要这样创建:
WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
#2
原因应该不是你说的,你看了《windows网络编程2版》的p140吗?它举的例子都是用socket创建的。
#3
参考MSDN的WSASend():
For overlapped sockets (created using WSASocket with flag WSA_FLAG_OVERLAPPED) sending information uses overlapped I/O, unless both lpOverlapped and lpCompletionRoutine are NULL. In that case, the socket is treated as a nonoverlapped socket.
For overlapped sockets (created using WSASocket with flag WSA_FLAG_OVERLAPPED) sending information uses overlapped I/O, unless both lpOverlapped and lpCompletionRoutine are NULL. In that case, the socket is treated as a nonoverlapped socket.
#4
谢谢楼上的热情,我解决了,还是用的socket
但还有一个问题:
服务使用的AcceptEx,那客户连接时怎样操作更好?
我现在使用的是connect,send,因为服务要收到至少一个字的缓冲才连接返回,但这样一来,服务回收刚才连接时收到的那条数据,也就是说,我不希望触发IO_ACCEPT后再次触发IO_RECV,不知道你有何高见?
但还有一个问题:
服务使用的AcceptEx,那客户连接时怎样操作更好?
我现在使用的是connect,send,因为服务要收到至少一个字的缓冲才连接返回,但这样一来,服务回收刚才连接时收到的那条数据,也就是说,我不希望触发IO_ACCEPT后再次触发IO_RECV,不知道你有何高见?
#5
我觉得客户端connect+send,服务端acceptex接到连接,并收到数据,不会再触发IO_RECV;
要不你试试WSAConnect()
要不你试试WSAConnect()
#6
我用WSAConnect试了,返回0,但服务的GetQueuedCompletionStatus一直阻塞没返回,也就是说它没收到数据。
#7
up
#1
你的socket句柄要这样创建:
WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
#2
原因应该不是你说的,你看了《windows网络编程2版》的p140吗?它举的例子都是用socket创建的。
#3
参考MSDN的WSASend():
For overlapped sockets (created using WSASocket with flag WSA_FLAG_OVERLAPPED) sending information uses overlapped I/O, unless both lpOverlapped and lpCompletionRoutine are NULL. In that case, the socket is treated as a nonoverlapped socket.
For overlapped sockets (created using WSASocket with flag WSA_FLAG_OVERLAPPED) sending information uses overlapped I/O, unless both lpOverlapped and lpCompletionRoutine are NULL. In that case, the socket is treated as a nonoverlapped socket.
#4
谢谢楼上的热情,我解决了,还是用的socket
但还有一个问题:
服务使用的AcceptEx,那客户连接时怎样操作更好?
我现在使用的是connect,send,因为服务要收到至少一个字的缓冲才连接返回,但这样一来,服务回收刚才连接时收到的那条数据,也就是说,我不希望触发IO_ACCEPT后再次触发IO_RECV,不知道你有何高见?
但还有一个问题:
服务使用的AcceptEx,那客户连接时怎样操作更好?
我现在使用的是connect,send,因为服务要收到至少一个字的缓冲才连接返回,但这样一来,服务回收刚才连接时收到的那条数据,也就是说,我不希望触发IO_ACCEPT后再次触发IO_RECV,不知道你有何高见?
#5
我觉得客户端connect+send,服务端acceptex接到连接,并收到数据,不会再触发IO_RECV;
要不你试试WSAConnect()
要不你试试WSAConnect()
#6
我用WSAConnect试了,返回0,但服务的GetQueuedCompletionStatus一直阻塞没返回,也就是说它没收到数据。
#7
up