⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpsocket.cpp

📁 wince系统下的网络编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	if(!m_bCreated)
	{
		return FALSE;
	}
	if(!m_bAuto)
	{
		return FALSE;
	}

	DWORD exitcode;
	m_bAuto=FALSE;
	//停止接收线程
	WaitForSingleObject(m_hClientThread,500);
	if(!GetExitCodeThread(m_hClientThread,&exitcode))
	{
		TerminateThread(m_hClientThread,exitcode);
	}
	CloseHandle(m_hClientThread);
	m_hClientThread=NULL;

	return TRUE;
}

int CTCPSocket::ReceiveClient(char* data, int length,int timeout)
{
	if(m_nType==TCP_SOCKET_SERVER)
	{
		return -3;
	}
	if(!m_bCreated)
	{
		return -2;
	}

	HANDLE hThread;
	DWORD dwThreadId;

	TimeOutParameter TimeOut;

	TimeOut.bExit=FALSE;
	TimeOut.bFinished=FALSE;
	TimeOut.EndTime=timeout;
	TimeOut.nNo=-1;
	TimeOut.pbConnected=&(m_bAuto);
	TimeOut.phDataThread=&(m_hClientThread);
	TimeOut.pnConnections=&(m_bCreated);
	TimeOut.s=m_sSocket;

	hThread=CreateThread(NULL,0,TimeOutControl,(LPVOID)&TimeOut,0,&dwThreadId);

	if(hThread==NULL)
	{
		return -3;
	}

	int nRet=recv(m_sSocket,data,length,0);
	if(nRet==SOCKET_ERROR)
	{
		error=WSAGetLastError();
	}
	TimeOut.bFinished=TRUE;

	while(!TimeOut.bExit)
	{
		Sleep(1);
	}

	return nRet;
}

int CTCPSocket::SendClient(char* data,int length)
{
	if(m_nType==TCP_SOCKET_SERVER)
	{
		return -3;
	}
	if(!m_bCreated)
	{
		return -2;
	}

	int nRet=send(m_sSocket,data,length,0);
	if(nRet==SOCKET_ERROR)
	{
		error=WSAGetLastError();
	}

	return nRet;
}

void CTCPSocket::Close()
{
	if(m_nType==TCP_SOCKET_SERVER)
	{
		StopServer();
		m_bCreated=FALSE;
	}
	else
	{
		StopReceiving();
		shutdown(m_sSocket,SD_RECEIVE);
		closesocket(m_sSocket);
		m_sSocket=NULL;
		m_bCreated=FALSE;
	}
	WSACleanup();
}

/////////////////////////////////////////////////////////////////////////////
//Protected Functions

BOOL CTCPSocket::Initwinsock()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	
	wVersionRequested=MAKEWORD(2,2);
	
	if(WSAStartup(wVersionRequested,&wsaData)==0)
	{
		return TRUE;
	}
	else
	{
		WSACleanup();
		return FALSE;
	}
}

BOOL CTCPSocket::NewConnect(int nNo)
{
	//建立一个接收数据的线程
	m_bConnected[nNo]=TRUE;
	m_hServerDataThread[nNo]=CreateThread(NULL,0,DataThread,this,0,NULL);
	if(m_hServerDataThread==NULL)
	{
		m_bConnected[nNo]=FALSE;
		closesocket(m_sServer[nNo]);
		return FALSE;
	}
	m_nConnections++;

	return TRUE;
}

DWORD WINAPI CTCPSocket::ServerThread(LPVOID lpParameter)
{
	CTCPSocket* m_pTCP=(CTCPSocket*)lpParameter;

	SOCKET sClient;
	int iAddrSize;
	struct sockaddr_in addr;
	int i;

	iAddrSize=sizeof(addr);

	//不断监听连接
	while(m_pTCP->m_bAuto)
	{
		sClient=accept(m_pTCP->m_sSocket,(struct sockaddr*)&addr,&iAddrSize);
		if(sClient==SOCKET_ERROR)
		{
			continue;
		}
		//判断是否达到最大连接数
		if(m_pTCP->m_nConnections>=MAX_CONNECTION)
		{
			closesocket(sClient);
			continue;
		}

		//没有则开始一个线程处理这个的收发
		for(i=0;i<MAX_CONNECTION;i++)
		{
			if(!(m_pTCP->m_bConnected[i]))
			{
				break;
			}
		}
		sprintf(m_pTCP->m_cIp[i],"%3d.%3d.%3d.%3d",addr.sin_addr.S_un.S_un_b.s_b1,addr.sin_addr.S_un.S_un_b.s_b2,addr.sin_addr.S_un.S_un_b.s_b3,addr.sin_addr.S_un.S_un_b.s_b4);
		TRACE("%s已经连接! 序号%d\n",m_pTCP->m_cIp[i],i);

		//回调处理
		if(m_pTCP->m_lpServerStatusProc!=NULL)
		{
			char* inf;
			inf=new char[22];
			sprintf(inf,"S%sC%3d",m_pTCP->m_cIp[i],i);
			m_pTCP->m_lpServerStatusProc(inf,22,m_pTCP->m_dwUserData);
			delete inf;
		}

		m_pTCP->m_sServer[i]=sClient;
		m_pTCP->m_nCurrent=i;
		m_pTCP->NewConnect(i);
	}

	return 0;
}

DWORD WINAPI CTCPSocket::DataThread(LPVOID lpParameter)
{
	CTCPSocket* m_pTCP=(CTCPSocket*)lpParameter;
	int MyNumber=m_pTCP->m_nCurrent;

	int nRet;
	char buf[512];
	
	timeval tv={0,5000};
	fd_set fs;

	//不断接收每个已经连接的客户的数据
	while(m_pTCP->m_bConnected[MyNumber])
	{
		FD_ZERO(&fs);
		FD_SET(m_pTCP->m_sServer[MyNumber],&fs);
		if(select(1,&fs,NULL,NULL,&tv)==1)
		{
			nRet=recv(m_pTCP->m_sServer[MyNumber],buf,512,0);
			
			if(nRet==SOCKET_ERROR)
			{
				//出错断开(例如客户端执行了超时操作导致自己断开)
				m_pTCP->error=WSAGetLastError();
				closesocket(m_pTCP->m_sServer[MyNumber]);
				m_pTCP->m_bConnected[MyNumber]=FALSE;
				m_pTCP->m_nConnections--;
				TRACE("%s出错断开! 序号%d\n",m_pTCP->m_cIp[MyNumber],MyNumber);

				//回调处理
				if(m_pTCP->m_lpServerStatusProc!=NULL)
				{
					char* inf;
					inf=new char[22];
					sprintf(inf,"S%sD%3d",m_pTCP->m_cIp[MyNumber],MyNumber);
					m_pTCP->m_lpServerStatusProc(inf,22,m_pTCP->m_dwUserData);
					delete inf;
				}

				break;
			}
			
			if(nRet>0)
			{
				//收到新的数据
				TRACE("收到%s数据%d字节! 序号%d\n",m_pTCP->m_cIp[MyNumber],nRet,MyNumber);

				//数据回调处理
				if(m_pTCP->m_lpServerDataArriveProc!=NULL)
				{
					char* inf;
					inf=new char[nRet+21];
					sprintf(inf,"S%s%3d",m_pTCP->m_cIp[MyNumber],MyNumber);
					memcpy(inf+21,buf,nRet);
					m_pTCP->m_lpServerDataArriveProc(inf,nRet+21,m_pTCP->m_dwUserData);
					delete inf;
				}

				continue;
			}
			
			if(nRet==0)
			{
				//客户断开
				TRACE("%s正常断开! 序号%d\n",m_pTCP->m_cIp[MyNumber],MyNumber);

				//回调处理
				if(m_pTCP->m_lpServerStatusProc!=NULL)
				{
					char* inf;
					inf=new char[22];
					sprintf(inf,"S%sD%3d",m_pTCP->m_cIp[MyNumber],MyNumber);
					m_pTCP->m_lpServerStatusProc(inf,22,m_pTCP->m_dwUserData);
					delete inf;
				}

				closesocket(m_pTCP->m_sServer[MyNumber]);
				m_pTCP->m_bConnected[MyNumber]=FALSE;
				m_pTCP->m_nConnections--;
				break;
			}
		}
	}

	return 0;
}

DWORD WINAPI CTCPSocket::ClientThread(LPVOID lpParameter)
{
	CTCPSocket* m_pTCP=(CTCPSocket*)lpParameter;

	int nRet;
	char buf[256];
	
	timeval tv={0,5000};
	fd_set fs;

	//不断接收服务器发来数据
	while(m_pTCP->m_bAuto)
	{
		FD_ZERO(&fs);
		FD_SET(m_pTCP->m_sSocket,&fs);
		if(select(1,&fs,NULL,NULL,&tv)==1)
		{
			nRet=recv(m_pTCP->m_sSocket,buf,256,0);
			
			if(nRet==SOCKET_ERROR)
			{
				//出错断开(例如服务器关闭)
				m_pTCP->error=WSAGetLastError();
				closesocket(m_pTCP->m_sSocket);
				m_pTCP->m_bAuto=FALSE;
				TRACE("客户端出错断开! \n");

				//回调处理
				if(m_pTCP->m_lpClientStatusProc!=NULL)
				{
					char* inf;
					inf=new char[22];					
					inf[0]='C';
					inf[1]='D';
					m_pTCP->m_lpClientStatusProc(inf,22,m_pTCP->m_dwUserData);
					delete inf;
				}

				break;
			}
			
			if(nRet>0)
			{
				//收到新的数据
				TRACE("客户端收到数据%d字节! \n",nRet);

				//数据回调处理
				if(m_pTCP->m_lpClientDataArriveProc!=NULL)
				{
					char* inf;
					inf=new char[nRet+1];
					inf[0]='C';
					memcpy(inf+1,buf,nRet);
					m_pTCP->m_lpClientDataArriveProc(inf,nRet+1,m_pTCP->m_dwUserData);
					delete inf;
				}

				continue;
			}
			
			if(nRet==0)
			{
				//服务器正常断开
				TRACE("客户端正常断开! \n");

				//回调处理
				if(m_pTCP->m_lpClientStatusProc!=NULL)
				{
					char* inf;
					inf=new char[22];					
					inf[0]='C';
					inf[1]='D';				
					m_pTCP->m_lpClientStatusProc(inf,22,m_pTCP->m_dwUserData);
					delete inf;
				}
				closesocket(m_pTCP->m_sSocket);
				m_pTCP->m_bAuto=FALSE;

				break;
			}
		}
	}

	return 0;
}

DWORD WINAPI CTCPSocket::TimeOutControl(LPVOID lpParameter)
{
	TimeOutParameter* m_pTimeOut=(TimeOutParameter*)lpParameter;

	time_t starttime,endtime;
	BOOL bTimeOut=FALSE;

	starttime=time(NULL);
	while(!bTimeOut)
	{
		if(m_pTimeOut->bFinished)
		{
			m_pTimeOut->bExit=TRUE;
			return 1;
		}
		Sleep(1);
		endtime=time(NULL);
		if((endtime-starttime)>m_pTimeOut->EndTime)
		{
			//超时
			bTimeOut=TRUE;
		}
	}

	//断开对应连接
	DWORD exitcode;
	if(m_pTimeOut->bFinished)
	{
		return 1;
	}
	if(m_pTimeOut->s!=NULL)
	{
		if(m_pTimeOut->nNo>=0)
		{
			//服务器socket
			//停止该接收线程
			*(m_pTimeOut->pbConnected)=FALSE;
			WaitForSingleObject(*(m_pTimeOut->phDataThread),50);
			if(!GetExitCodeThread(*(m_pTimeOut->phDataThread),&exitcode))
			{
				TerminateThread(*(m_pTimeOut->phDataThread),exitcode);
			}
			shutdown(m_pTimeOut->s,SD_RECEIVE);
			closesocket(m_pTimeOut->s);
			m_pTimeOut->s=NULL;
			CloseHandle(*(m_pTimeOut->phDataThread));
			*(m_pTimeOut->phDataThread)=NULL;
			*(m_pTimeOut->pnConnections)--;
			
		}
		else
		{
			//停止客户端接收线程
			if(*(m_pTimeOut->pbConnected))
			{
				*(m_pTimeOut->pbConnected)=FALSE;
				WaitForSingleObject(*(m_pTimeOut->phDataThread),50);
				if(!GetExitCodeThread(*(m_pTimeOut->phDataThread),&exitcode))
				{
					TerminateThread(*(m_pTimeOut->phDataThread),exitcode);
				}
			}
			shutdown(m_pTimeOut->s,SD_RECEIVE);
			closesocket(m_pTimeOut->s);
			m_pTimeOut->s=NULL;
			CloseHandle(*(m_pTimeOut->phDataThread));
			*(m_pTimeOut->phDataThread)=NULL;
			*(m_pTimeOut->pnConnections)=FALSE;
		}
	}

	m_pTimeOut->bExit=TRUE;
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -