在线程里循环收发数据的问题

今天写了一个客户端,用的是winsock2库,开了两个线程,一个是发心跳包,一个是接收服务器发送过来的行情,却出现了一个意想不到的Bug:编译连接都没问题,运行exe时,却直接退出来了,根本就没有进入到线程的循环。

这是为什么呢,郁闷了很久!解决办法:_beginthreadex后,加一句while(ture){}。

但是问题又来了,把它从Console上转换到App上是,不能用while(true){}, 在接收线程中,一直都接收不到数据。

解决办法--

另外用iocp写一个客户

//temp.h
#include <WINSOCK2.H>
#include <windows.h>
#include <stdio.h>
#include <process.h>
#pragma  comment(lib,"ws2_32")
#define  DATA_LEN 1024
HANDLE hIocp;

enum
{
	IO_READ =0,
	IO_WRITE,
	IO_CONNECTED,
	IO_UNDEFINE
};
class Per_Handle_Data
{
public:
	SOCKET s_Socket;
};
class Per_Io_Data
{
public:
	OVERLAPPED O_Overlapped;
	WSABUF     buff;
	BYTE       Data[DATA_LEN];
	int        IO_TYPE;
};
void PostIocpSend(SOCKET sockets,BYTE *data,int datalen)
{
	Per_Io_Data *p_Io_Data=new Per_Io_Data;
	memcpy(&p_Io_Data->Data,data ,datalen);
	p_Io_Data->buff.buf=(char *)p_Io_Data->Data;
	p_Io_Data->buff.len=datalen;
	p_Io_Data->IO_TYPE=IO_WRITE;

	ZeroMemory(&p_Io_Data->O_Overlapped,sizeof(OVERLAPPED));

	DWORD Bytes;
	DWORD Flags=0;
	WSASend(sockets,&p_Io_Data->buff,1,&Bytes,Flags,&p_Io_Data->O_Overlapped,NULL);
}
void PostIocpRecv(Per_Handle_Data *Iocp_Handle_Data)
{
	Per_Io_Data *p_Io_Data=new Per_Io_Data;
	p_Io_Data->buff.buf=(char *)p_Io_Data->Data;
	p_Io_Data->buff.len=DATA_LEN;
	p_Io_Data->IO_TYPE=IO_READ;
	ZeroMemory(&p_Io_Data->O_Overlapped,sizeof(OVERLAPPED));
	DWORD Bytes;
	DWORD Flags=0;
	WSARecv(Iocp_Handle_Data->s_Socket,&p_Io_Data->buff,1,&Bytes,&Flags,&p_Io_Data->O_Overlapped,NULL);
}
unsigned int __stdcall HeartbeatThread(LPVOID Lparam)
{
	SOCKET _socket = *(SOCKET*)Lparam;
	char data[8] = {0};
	strcpy(data, "\n");
	while(true)
	{
		PostIocpSend(_socket,(BYTE *)data,strlen(data)+1);
		Sleep(100);
	}
	return 0;
}
/*DWORD WINAPI */unsigned int __stdcall WorkerThread(LPVOID Lparam)
{
	::AllocConsole();    // 打开控件台资源
	freopen("CONOUT$", "w+t", stdout);    // 申请写
	freopen( "CONIN$", "r+t", stdin ); // 申请读
	printf("call console successfully !\n");

	int checkCount = 0;
	while(true)
	{
		Per_Handle_Data *Lp_Handle_Data;
		Per_Io_Data     *Lp_Io_Data;
		OVERLAPPED               *m_Overlapped;
		DWORD Bytes;
		if(GetQueuedCompletionStatus((HANDLE)Lparam,&Bytes,
			(PULONG_PTR)&Lp_Handle_Data,(struct _OVERLAPPED ** )&m_Overlapped,WSA_INFINITE)==FALSE)
		{
			printf("Remote Server (Socket %d) Has Gone !!\r\n",Lp_Handle_Data->s_Socket);
			closesocket(Lp_Handle_Data->s_Socket);
			delete Lp_Handle_Data;
			delete Lp_Io_Data;
			return 0;
		}
		Lp_Io_Data = (Per_Io_Data *)CONTAINING_RECORD(m_Overlapped, Per_Io_Data, O_Overlapped);
		printf("Request Comming !!\r\n");
		if (Bytes<=0&&Lp_Io_Data->IO_TYPE!=IO_CONNECTED)
		{
			printf("Remote Server (Socket %d) Has Gone !!\r\n",Lp_Handle_Data->s_Socket);
			closesocket(Lp_Handle_Data->s_Socket);
			delete Lp_Handle_Data;
			delete Lp_Io_Data;
			return 0;
		}

		switch(Lp_Io_Data->IO_TYPE)
		{
		case IO_CONNECTED:
			printf("IO_CONNECTED !\r\n");
			// PostIocpSend(Lp_Handle_Data);
			PostIocpRecv(Lp_Handle_Data);
			delete Lp_Io_Data;
			break;
		case IO_READ:
			{
				printf("IO_READ \r\nData : %s\r\n",Lp_Io_Data->Data);
				PostIocpRecv(Lp_Handle_Data);
				delete Lp_Io_Data;
				//break;
				if(checkCount < 2)
				{
					checkCount++;
					char checkBuf[16];
					strcpy(checkBuf, "user2\r\n");
					PostIocpSend(Lp_Handle_Data->s_Socket, (BYTE*)checkBuf, strlen(checkBuf));
					delete Lp_Io_Data;
					break;
				}
				break;
			}

		case IO_WRITE:
			printf("IO_WRITE \r\n");
			// PostIocpSend(Lp_Handle_Data);
			delete Lp_Io_Data;
			break;
		case  IO_UNDEFINE:
			printf("IO_UNDEFINE \r\n");
			delete Lp_Io_Data;
			break;
		default: break;
		}
	}
	return 0;
}
int my_main()
{
	hIocp=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,0);
	//CreateThread(NULL,0,WorkerThread,hIocp,0,NULL);
	_beginthreadex(NULL, 0, WorkerThread, hIocp, 0, NULL);
	WSAData wsa;
	WSAStartup(MAKEWORD(2,2),&wsa);
	SOCKET m_Socket=WSASocket(AF_INET,SOCK_STREAM,0,NULL,NULL,WSA_FLAG_OVERLAPPED);
	sockaddr_in S_Addr;
	S_Addr.sin_family=AF_INET;
	S_Addr.sin_addr.S_un.S_addr=inet_addr("171.265.169.339");
	S_Addr.sin_port=htons(8888);
	//while(connect(m_Socket,(sockaddr *)&S_Addr,sizeof(sockaddr))==SOCKET_ERROR) Sleep(100);
	connect(m_Socket,(sockaddr *)&S_Addr,sizeof(sockaddr));

	Per_Handle_Data *p_Handle_Data=new Per_Handle_Data;
	p_Handle_Data->s_Socket=m_Socket;
	CreateIoCompletionPort((HANDLE)m_Socket,hIocp,(ULONG_PTR)p_Handle_Data,0);

	Per_Io_Data *p_Io_Data=new Per_Io_Data;
	p_Io_Data->IO_TYPE=IO_CONNECTED;
	ZeroMemory(&p_Io_Data->O_Overlapped,sizeof(OVERLAPPED));
	PostQueuedCompletionStatus(hIocp,0,(ULONG_PTR)p_Handle_Data,(LPOVERLAPPED)&p_Io_Data->O_Overlapped);
	//while(true)
	//{
	//	//char data[1024]={0};
	//	//gets(data);
	//	//PostIocpSend(m_Socket,(BYTE *)data,strlen(data)+1);
	//}
	//_beginthreadex(NULL, 0, HeartbeatThread, (LPVOID)&m_Socket, 0, NULL);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值