今天写了一个客户端,用的是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;
}