Click here to Skip to main content
15,891,033 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
My IOCP client can send data but can't rev data, why?
C++
#include "assert.h"
#include <winsock2.h>
#include <mswsock.h>
#include <process.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"mswsock.lib")

#include "iostream"
using namespace std;

struct IODATA
{
	OVERLAPPED ol;
	DWORD op;
	SOCKET s;
	HANDLE hIocp;
	char *buff;				// I/O操作使用的缓冲区
	int nLen;				// buff缓冲区(使用的)大小
};

char szSendMsg[4096]={0};
char szRevMsg[4096]={0};
#define CONNCHECKDATA "hello0123456"
IODATA io={0};

DWORD WINAPI SendThread(LPVOID lpparam);

int main(int argc, char* argv[])
{
	int ret=0;
	DWORD bytes=0;
	WSADATA data={0};
	static LPFN_CONNECTEX lpfnConnectEx=NULL;
	int iRet=WSAStartup(0x0202,&data);

	HANDLE hIocp=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
	
	io.s=socket(AF_INET,SOCK_STREAM,0);
	io.op=FD_CONNECT;
	io.hIocp=hIocp;
	

	SOCKADDR_IN lAddr,rAddr;
	lAddr.sin_family=AF_INET;
	lAddr.sin_port=INADDR_ANY;
	lAddr.sin_addr.s_addr = INADDR_ANY;

	rAddr.sin_family=AF_INET;
	rAddr.sin_port=htons(4567);
	rAddr.sin_addr.s_addr=inet_addr("127.0.0.1");

	ret=bind(io.s,(SOCKADDR*)&lAddr,sizeof(lAddr));
	CreateIoCompletionPort((HANDLE)io.s,hIocp,(ULONG_PTR)&io,0);

	if(NULL==lpfnConnectEx)
	{
		GUID guid=WSAID_CONNECTEX;
		ret=WSAIoctl(io.s,SIO_GET_EXTENSION_FUNCTION_POINTER,&guid,sizeof(guid),&lpfnConnectEx,sizeof(lpfnConnectEx),&bytes,NULL,NULL);
	}

	//    _beginthreadex(NULL,0,_IoHandle,&io,0,NULL);  

	printf("connecting...\n");

	char SendBuffer[4096]={0};
	char* pMask = (char*)SendBuffer;
	*pMask=128;
	strcpy(pMask+3,CONNCHECKDATA);
	*(WORD*)(pMask+1) = strlen(CONNCHECKDATA)+1;
	ret=lpfnConnectEx(io.s,(SOCKADDR*)&rAddr,sizeof(rAddr),SendBuffer,*(WORD*)(pMask+1) + 3,&bytes,&io.ol);

	/*
	BOOL bResult = m_lpfnConnectEx (m_sockClient , 
		(sockaddr *)&addrPeer ,  // [in] 对方地址 
		nLen ,               // [in] 对方地址长度 
		lpSendBuffer ,       // [in] 连接后要发送的内容,这里不用 
		dwSendDataLength ,   // [in] 发送内容的字节数 ,这里不用 
		&dwBytesSent ,       // [out] 发送了多少个字节,这里不用 
		(OVERLAPPED *)pmyoverlapped ); // [in] 这东西复杂,下一篇有详解 
		*/


	DWORD dwTick=GetTickCount();
	while(1)
	{
		IODATA* pio=NULL;
		LPOVERLAPPED pol=NULL;
		//ret=GetQueuedCompletionStatus(hIocp,&bytes,(PULONG_PTR)&pio,&pol,1000);
		ret = ::GetQueuedCompletionStatus(hIocp,&bytes,(PULONG_PTR)&pio,&pol,WSA_INFINITE);

		printf("GQCS returned  ---  ");
		if(!pio)
		{
			printf("GQCS timeout.closesocket[socket=%d] -%d\n",io.s,GetTickCount()-dwTick);
			if(ret==0)
			{
				shutdown(io.s,SD_BOTH);
				closesocket(io.s);                
			}
		}
		else
		{
			if(pio->op==FD_CONNECT)
			{
				if(ret)
				{
					printf("connect OK, recving[socket=%d]...\n",pio->s);

					IODATA *pData = new IODATA;
					*pData = *pio;
					WSABUF wb;
					wb.buf=szRevMsg;
					wb.len=4096;
					pData->op = FD_READ;
					pData->buff = wb.buf;
					pData->nLen = wb.len;
					// Post another receive operation
					DWORD dwFlags = 0;
					DWORD dwRecvBytes;

					// Set up the per-I/O operation data for the next
					// overlapped call
					ZeroMemory(&(pData->ol), sizeof(OVERLAPPED));

					ret=WSARecv(pData->s,&wb,1,&dwRecvBytes,&dwFlags,&pData->ol,NULL);
					if (ret!=0)
					{
						if(::WSAGetLastError() != WSA_IO_PENDING)
						{
							printf("rev err:%d\n",WSAGetLastError());
						}
					}		

					HANDLE hthread;
					DWORD dwthreadid;
					hthread=CreateThread(NULL,0,SendThread,(LPVOID)0,0,&dwthreadid);
					if(hthread==NULL)
					{
						printf("fail55\n");
					}
					CloseHandle(hthread);
					continue;
				}
				else
				{
					printf("%s[%d] failed %d\n",pio->op==FD_CONNECT ? "Connect" : "Recv",pio->s,WSAGetLastError());
					break;
				}
			}
			else if(pio->op==FD_READ)
			{
				long *pLen = (long *)pio->buff;
				//assert(*pLen == bytes);

				pio->buff[bytes]=0;
				printf("printf returned[%d] MSG:%s\n",bytes,pio->buff+sizeof(long));

				continue;
			}
			else if (pio->op==FD_WRITE)
			{
// 				WSABUF wb;
// 				wb.buf=new char[4096];
// 				char* pMask = (char*)wb.buf;
// 				*pMask=128;
// 				strcpy(wb.buf+3,CONNCHECKDATA);
// 				*(WORD*)(pMask+1) = strlen(CONNCHECKDATA)+1;
// 				wb.len=*(WORD*)(pMask+1)+3;
// 				pio->op = FD_WRITE;
// 				ret=WSASend(pio->s,&wb,1,&bytes,0,&pio->ol,NULL);

				
				continue;
			}
		}
	}

	system("pause");
	return 0;
}

DWORD WINAPI SendThread(LPVOID lpparam)
{
	//int num=(int)lpparam;

	while (true)
	{
		cout<<"发送..."<<endl;
		WSABUF wb;
		wb.buf=szSendMsg;
		char* pMask = (char*)wb.buf;
		*pMask=128;
		strcpy(wb.buf+3,"测试数据abcd...");
		*(WORD*)(pMask+1) = strlen("测试数据abcd...")+1;
		wb.len=*(WORD*)(pMask+1)+3;
		io.op = FD_WRITE;
		io.buff = wb.buf;
		io.nLen = wb.len;
		DWORD bytes = 0 ;
		int ret=WSASend(io.s,&wb,1,&bytes,0,&io.ol,NULL);
		if (ret!=0)
		{
			printf("rev err:%d\n",WSAGetLastError());
		}		
		cin.get();
	}
	


	return 0;
}
Posted
Updated 8-Jun-10 22:56pm
v2
Comments
Richard MacCutchan 9-Jun-10 7:32am    
Please explain what you mean; do you get a bad return code, system error, exception etc?

1 solution

how can I do

When The Server Send Data quickly
 
Share this answer
 
Comments
Richard MacCutchan 9-Jun-10 12:54pm    
Not sure I understand, but you need to keep receiving until the server stops sending.
henry3695 9-Jun-10 18:18pm    
you means may be Open A new Thread to receiving data?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900