TCP IOCP istemcisini uygularken bazı sorun yaşıyorum. Mac OSX üzerinde küme gerçekleştirdim, bu yüzden pencereler üzerinde benzer bir şey yapmak istiyordum ve benim anlayışım IOCP'nin en yakın şey olduğudur. Asıl sorun GetCompetetionStatus'un asla geri dönmemesi ve zaman aşımına uğramasıdır. İzlemek için tanıtıcıyı oluştururken bir şeyleri kaçırdığımı, ancak ne olduğundan emin olmadığımı varsayalım. Şimdiye kadar aldık burasıdır:IOCP C++ TCP istemcisi
Benim bağlantı rutin: Burada
struct sockaddr_in server;
struct hostent *hp;
SOCKET sckfd;
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if ((hp = gethostbyname(host)) == NULL)
return NULL;
WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED)
if ((sckfd = WSASocket(AF_INET,SOCK_STREAM,0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("Error at socket(): Socket\n");
WSACleanup();
return NULL;
}
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr = *((struct in_addr *)hp->h_addr);
memset(&(server.sin_zero), 0, 8);
//non zero means non blocking. 0 is blocking.
u_long iMode = -1;
iResult = ioctlsocket(sckfd, FIONBIO, &iMode);
if (iResult != NO_ERROR)
printf("ioctlsocket failed with error: %ld\n", iResult);
HANDLE hNewIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, ulKey, 0);
CreateIoCompletionPort((HANDLE)sckfd, hNewIOCP , ulKey, 0);
connect(sckfd, (struct sockaddr *)&server, sizeof(struct sockaddr));
//WSAConnect(sckfd, (struct sockaddr *)&server, sizeof(struct sockaddr),NULL,NULL,NULL,NULL);
return sckfd;
gönderme rutindir (netlik için işleme bazı hata kaldırın):
(aynı zamanda netlik için işleme bazı hata kaldırmak)
IOPortConnect(int ServerSocket,int timeout,string& data){
char buf[BUFSIZE];
strcpy(buf,data.c_str());
WSABUF buffer = { BUFSIZE,buf };
DWORD bytes_recvd;
int r;
ULONG_PTR ulKey = 0;
OVERLAPPED overlapped;
OVERLAPPED* pov = NULL;
HANDLE port;
HANDLE hNewIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, ulKey, 0);
CreateIoCompletionPort((HANDLE)ServerSocket, hNewIOCP , ulKey, 0);
BOOL get = GetQueuedCompletionStatus(hNewIOCP,&bytes_recvd,&ulKey,&pov,timeout*1000);
if(!get)
printf("waiton server failed. Error: %d\n",WSAGetLastError());
if(!pov)
printf("waiton server failed. Error: %d\n",WSAGetLastError());
port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, (u_long)0, 0);
SecureZeroMemory((PVOID) & overlapped, sizeof (WSAOVERLAPPED));
r = WSASend(ServerSocket, &buffer, 1, &bytes_recvd, NULL, &overlapped, NULL);
printf("WSA returned: %d WSALastError: %d\n",r,WSAGetLastError());
if(r != 0)
{
printf("WSASend failed %d\n",GetLastError());
printf("Bytes transfered: %d\n",bytes_recvd);
}
if (WSAGetLastError() == WSA_IO_PENDING)
printf("we are async.\n");
CreateIoCompletionPort(port, &overlapped.hEvent,ulKey, 0);
BOOL test = GetQueuedCompletionStatus(port,&bytes_recvd,&ulKey,&pov,timeout*1000);
CloseHandle(port);
return true;
}
Herhangi bir içgörü takdir edilecektir.
Gerçekten "CreateIoCompletionPort" öğesinden dönüş değerini kontrol ediyor musunuz? Her işlevdeki CreateIoCompletionPort öğesinin her ikisini de 87 (yanlış parametre) ve 6 hatası (geçersiz tanıtıcı) döndürdüğünde GetLastError öğesini koyarak –
. Her ikisi de geçerli tanıtıcıları (ServerSocket ve bağlantı noktası) oldukları için neden yanlış döndüklerinden emin değilim. – daltoniam