Server与Client的Socket连通了,并且能够使用send()发送数据到客户端来正常通讯。
IOCP线程也创建成功了,能从调试那里看见八个线程。
只是,在刚刚接收到clientSocket后进行WSARecv()操作返回-1,使用WSAGetLastError()得到结果为6。
检查了一个晚上,看不出问题来,求各路人士帮忙看看,走过路过都帮顶顶~
将部分代码粘上:
// 这函数用于创建IOCP的ServerSocket.
void IocpServerSocket::startServer(DataManage * elem)
{
this -> IocpServerSocket::setDataManage(elem); // 按照最传统的流程来的啦~
this -> IocpServerSocket::createIocpHandle();
this -> IocpServerSocket::createWordThread();
this -> BaseSocket::createTcpSocket();
this -> ServerSocket::sbind();
this -> ServerSocket::slisten();
this -> IocpServerSocket::createAcceptClientThread();
return;
}
// 用于接收客户端Socket的线程
DWORD WINAPI IocpServerSocket::acceptClientThread(LPVOID IpParam)
{
IocpServerSocket * myIocp = (IocpServerSocket *) IpParam;
BaseSocket accClient;
while(true){
if(myIocp -> acceptClientSocket(accClient)){ // 接收客户端
myIocp -> connectClientIocp(accClient); // 客户端连接IOCP
myIocp -> createSocketRevRequest(accClient); // 创建从客户端的IOCP接收数据请求
if(NULL != myIocp->dataManage){
myIocp->dataManage->afterAcceSock(accClient);
}
}
}
return 0;
}
acceptClientSocket运行正常。。 就不粘上来啦~
int IocpServerSocket::connectClientIocp(const BaseSocket & elem)
{
// 创建用来和套接字关联的单句柄数据信息结构
BaseSocket * information = new BaseSocket(elem); // 再创指针是因为得将信息存放于(内存)堆中,删除操作将在数据获取函数中进行处理
// 将接受套接字和完成端口关联
HANDLE result = CreateIoCompletionPort((HANDLE)(information->getSocket()), completionPort, (DWORD)information, 0);
// ...
return 1;
}
下面这里不知道哪里错了,返回值是6
int IocpServerSocket::createSocketRevRequest(const BaseSocket & elem)
{
// 为投递I/O操作指定OVERLAPPED结构,在堆中创建好对象,准备在接收数据时再读取这对象的首地址
PerIoData * data = new PerIoData();
data -> operationType = PerIoData::readData;
data -> dataBuff.buf = data -> charBuf;
data -> dataBuff.len = PerIoData::defaultBufSize;
data -> dataByte = PerIoData::defaultBufSize;
DWORD Flags = 0; // 这数据很重要,在传参时不能删除,
int r = WSARecv(elem.getSocket(), &(data->dataBuff), 1, &data->dataByte, &Flags, &(data -> overlapped), NULL);
if(SOCKET_ERROR == r){
// #ifdef IO_STANDARD_STREAM_INFORMATION
std::cerr << "createSocketRevRequest Error:" << GetLastError() << std::endl;
system("pause");
// #endif
}
return r;
}
最后大家顺便看看这个有没错:
BaseSocket * outSocket = NULL; // 用以接收数据,起标志作用,无需初始化
PerIoData * outData = NULL;
int result = GetQueuedCompletionStatus(completionPort, &BytesTransferred, (PULONG_PTR)&outSocket, (LPOVERLAPPED*)&outData, WSA_INFINITE);
----------------------------------------------------
std::cerr << "createSocketRevRequest Error:" << GetLastError() << std::endl;
GetLastError为6,据 http://neicole.blog.51cto.com/5621716/974823 , 〖6〗-句柄无效.
不过IOCP不用句柄啊,重叠才用啊,然后就去找看看完成端口的句柄,发觉也正常啊,
completionPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0);
completionPort 非NULL.
然后。。。 不解,求解救~