www.pudn.com > shortestPathAlgorithmRouter.rar > CComm.cpp


#include "CComm.h" 
 
struct pTable{ 
	char	cName[10]; 
	int		iport;	 
}Port_Number[4]; 
 
struct routTable { 
	int		DesNode;  //目的结点 
	char	NextNode; //邻结点 
	char	node1; 
	char	node2; 
	char	node3; 
	char	node4; 
	char	node5; 
	int		iHop; 
	int		iAge; 
	int		iPort;	 
}RoutTable[10]; 
char	router_Array[10][10]; 
int		Tag=0; 
char	msg[5]; 
char	send_To; 
 
int tempport=0; 
char temp_Array[70]; 
 
CComm::CComm() 
{ 
	//构造函数 
	ListenSocket = INVALID_SOCKET;	            // 开始设置为INVALID_SOCKET 
	 
	#ifdef _WIN32	                            // 如果是win32系统 
		WORD VersionRequested = MAKEWORD(1,1);  //获取Socket版本号 
		WSADATA wsaData;                        //协商时使用的变量 
		 
		WSAStartup(VersionRequested, &wsaData);	// 启动winsock服务 
		if ( wsaData.wVersion != VersionRequested ) 
		{ 
			printf("Wrong version or WinSock not loaded\n"); 
			fflush(0);	 
		} 
	#endif 
} 
 
//析构函数 
CComm::~CComm() 
{ 
	if ( ListenSocket != INVALID_SOCKET ) 
		closesocket( ListenSocket );	// 如果已经创建、则关闭 
 
	#ifdef _WIN32	                    // 调用WSACleanup函数释放资源 
		WSACleanup(); 
	#endif 
} 
 
bool CComm::SendMessage( char *Msg, int Len, char *host, short port ) 
{	 
	signed int Sent; 
	hostent *hostdata; 
	if ( atoi(host) )	               // 是否IP地址为标准形式 
	{ 
		u_long ip = inet_addr( host ); 
		hostdata = gethostbyaddr( (char *)&ip, sizeof(ip), PF_INET ); 
	} 
	else	                           // 否则则可能是机器名 
	{ 
		hostdata = gethostbyname( host ); 
	} 
 
	if ( !hostdata ) 
	{ 
		printf("获得机器名错误\n"); 
		fflush(0); 
		return false; 
	} 
	 
	sockaddr_in dest;	               // 发送目标地址 
	dest.sin_family = PF_INET; 
	dest.sin_addr = *(in_addr *)(hostdata->h_addr_list[0]); 
	dest.sin_port = htons( port ); 
	printf("信息已经被发送到主机 %s 端口为 %i\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port)); 
	//数据发送 
	Sent = sendto(ListenSocket, Msg, Len, 0, (sockaddr *)&dest, sizeof(sockaddr_in)); 
	 
	if ( Sent != Len )                 //发送长度是否与实际长度相等 
	{ 
		printf("错误发送UDP信息\n"); 
		fflush(0); 
		return false; 
	} 
	 
	return true; 
} 
 
void *CComm::ListenThread( void *data ) 
{ 	 
	char bufR[4096]; 
	CComm *Comm = (CComm *)data; 
	int len = sizeof(Comm->client1); 
	while(1)	                       // 一直循环,直到有数据来 
	{ 
		 //接收数据 
		int result = recvfrom( Comm->ListenSocket, bufR, sizeof(bufR), 0, (sockaddr *)&Comm->client1, (socklen_t *)&len); 
		if ( result > 0 ) 
		{ 
			bufR[result] = 0; 
			 
			tempport=ntohs(Comm->client1.sin_port);	 
			if(bufR[0]=='@') 
			{	 
				strcpy(msg,bufR); 
				if(int(msg[2])=='0') 
				{	 
					if(msg[3]==RoutTable[0].DesNode+0x30) 
					   printf("\n收到%c测试信息,经过了%c跳!\n",msg[3],msg[4]); 
					else 
					{ 
						printf("\n丢失从%c到%c测试信息!\n",msg[3],msg[1]); 
						printf("\n>>D%c",msg[1]); 
					} 
						 
						 
				} 
				else 
				{	msg[2]=char(int(msg[2])-1);	 
				    msg[4]=char(int(msg[4])+1);	 
					send_To=msg[1]; 
					Tag=1; 
				} 
			} 
			else 
			{	 
				//路由表 
				strcpy(temp_Array,bufR); 
				Comm->changeRouter(tempport,temp_Array); 
			} 
			fflush(0); 
		} 
 
	}	 
} 
 
 
void *CComm::SendThread( void *data ) 
{	 
	signed int SentS; 
	char bufS[70]; 
	CComm *Comm = (CComm *)data; 
	int len = sizeof(Comm->client2); 
	Comm->client2.sin_addr.S_un.S_un_b.s_b1=127;  //输入本地地址 
	Comm->client2.sin_addr.S_un.S_un_b.s_b2=0; 
	Comm->client2.sin_addr.S_un.S_un_b.s_b3=0; 
	Comm->client2.sin_addr.S_un.S_un_b.s_b4=1; 
 
	sockaddr_in dest;	// 发送目标地址 
	dest.sin_family = PF_INET; 
	dest.sin_addr=Comm->client2.sin_addr; 
 
	//数据发送 
	while(1) 
	{	bufS[70]=0; 
		int iT; 
		    for(int i=0;i<10;i++) //do with routtable 
		{	 
			iT=i*7;			 
			bufS[iT]= RoutTable[i].DesNode+0x30; 
			bufS[iT+1]= RoutTable[i].NextNode; 
			bufS[iT+2]= RoutTable[i].node1; 
			bufS[iT+3]= RoutTable[i].node2; 
			bufS[iT+4]= RoutTable[i].node3; 
			bufS[iT+5]= RoutTable[i].node4; 
		    bufS[iT+6]= RoutTable[i].node5;	 
		} 
 
		Sleep(2000);   //插入两秒延时 
		if(Tag==0) 
			for(int kk=1;kk<4;kk++) 
			{	if(Port_Number[kk].iport!=0) 
				{			 
					dest.sin_port = htons(Port_Number[kk].iport); 
					SentS = sendto(Comm->ListenSocket, bufS, strlen(bufS), 0, (sockaddr *)&dest, sizeof(sockaddr_in)); 
					Sleep(300); 
				} 
			} 
		else 
		{	 
			bool bmaysend=false; 
			for(int i=0;i<10;i++) 
			{ 
				if(RoutTable[i].DesNode+0x30==send_To) 
				{				 
					if(RoutTable[i].NextNode =='*') 
					{ 
						printf("\n收到%c发送的信息,经过了%c跳!\n",msg[3],msg[4]); 
						bmaysend=false; 
						Tag=0; 
					} 
					else 
					{ 
					dest.sin_port = htons(RoutTable[i].iPort); 
					bmaysend=true; 
					printf("\n>>F%c\n",send_To,RoutTable[i].iPort); 
					}		 
				} 
			} 
			if(bmaysend) 
			{ 
				//调用sendto函数发送数据 
				SentS = sendto(Comm->ListenSocket, msg, strlen(msg), 0, (sockaddr *)&dest, sizeof(sockaddr_in)); 
				Tag=0; 
		 
			} 
		 
		} 
	} 
 
} 
//地址绑定,注意在UDP协议中,不需要listen,这里函数listen只是绑定一个端口 
bool CComm::Listen( int PortNum ) 
{ 
	ListenSocket = socket(PF_INET, SOCK_DGRAM, 0); 
		if ( ListenSocket == INVALID_SOCKET ) 
		{ 
			printf("Error: socket创建失败\n"); 
			fflush(0); 
			return false; 
		} 
 
	srv.sin_family = PF_INET; 
	srv.sin_addr.s_addr = htonl( INADDR_ANY );	// 任何地址 
	srv.sin_port = htons( PortNum ); 
 
		if ( bind( ListenSocket, (struct sockaddr *)&srv, sizeof(srv)) != 0 ) 
		{ 
			printf("Error: 绑定失败\n"); 
			fflush(0); 
			closesocket( ListenSocket ); 
			return false; 
		} 
 
		int ThreadID;	// 线程id	 
		DWORD thread; 
		//调用createthread创建线程 
		ThreadID = (int)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(CComm::ListenThread), (void *)this, 0, &thread); 
 
		int ThreadIDS;	// 线程id	 
		DWORD threadS; 
		//调用createthread创建线程 
		ThreadIDS = (int)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(CComm::SendThread), (void *)this, 0, &threadS); 
		int ThreadIDO;	// 线程id 
		DWORD threadO; 
		//调用createthread创建线程 
		ThreadIDO = (int)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(CComm::AnotherThread), (void *)this, 0, &threadO); 
		 
		return true; 
	 
} 
void *CComm::AnotherThread( void *data ) 
{ 
  while(1) 
  {		 
     
	  Sleep(2000); 
	  for(int i=1;i<10;i++) 
	  { 
		RoutTable[i].iAge=RoutTable[i].iAge+1; 
		if(RoutTable[i].iAge >3 || RoutTable[i].iHop>5) 
		{ 
				RoutTable[i].DesNode=0; 
				RoutTable[i].iHop=0; 
				RoutTable[i].NextNode='*'; 
				RoutTable[i].node1 ='*'; 
				RoutTable[i].node2 ='*'; 
				RoutTable[i].node3 ='*'; 
				RoutTable[i].node4 ='*'; 
				RoutTable[i].node5 ='*'; 
				RoutTable[i].iPort=0; 
				RoutTable[i].iAge=0; 
	 
		}   
	   
	  }  
 
 
  } 
 
} 
//处理路由数据 
void CComm::changeRouter(int iport,char *arr) 
{   char sendName=arr[0]; 
	int itemp=0; 
	bool isIN; 
 
	for(int m=1;m<10;m++) 
	{	 
		if(RoutTable[m].NextNode==sendName) //清空旧记录 
		{ 
				RoutTable[m].DesNode=0; 
				RoutTable[m].iHop=0; 
				RoutTable[m].NextNode='*'; 
				RoutTable[m].node1 ='*'; 
				RoutTable[m].node2 ='*'; 
				RoutTable[m].node3 ='*'; 
				RoutTable[m].node4 ='*'; 
				RoutTable[m].node5 ='*'; 
				RoutTable[m].iPort=0; 
				RoutTable[m].iAge=0;		 
		} 
	} 
 
 
	for(int k=0;k<10;k++) 
	{    
			itemp=k*7; 
			isIN=false; 
			if(arr[itemp]!='0' && arr[itemp]!=RoutTable[0].DesNode+0x30) 
			{ 
				for(int h=1;h<10;h++) 
				{ 
					if(RoutTable[h].DesNode==arr[itemp]-0x30) 
					{	 
						isIN=true;										 
						int itemphop=1; 
						for(int l=1;l<7;l++) 
						{ 
							if(arr[itemp+l]!='*') itemphop++; 
						} 
						if(itemphop<=RoutTable[h].iHop) 
						{										 
							RoutTable[h].DesNode=arr[itemp]-0x30; 
							RoutTable[h].iHop=itemphop; 
							RoutTable[h].NextNode=sendName; 
							RoutTable[h].node1 =arr[itemp+1]; 
							RoutTable[h].node2 =arr[itemp+2]; 
							RoutTable[h].node3 =arr[itemp+3]; 
							RoutTable[h].node4 =arr[itemp+4]; 
							RoutTable[h].node5 =arr[itemp+5]; 
							RoutTable[h].iPort=iport; 
							RoutTable[h].iAge=0; 
						} 
 
					} 
								 
				} //更新路由 
				if( !isIN )//新路由,找一空项,登记 
				{  
					bool findone=false; 
					for(int p=1;p<10;p++) 
					{    
						if(RoutTable[p].DesNode==0 && findone==false) 
						{ 
							findone=true;										 
							int itemphopN=1; 
							for(int l=1;l<7;l++) 
							{ 
								 if(arr[itemp+l]!='*') itemphopN++; 
							} 
										 
							RoutTable[p].DesNode=arr[itemp]-0x30; 
							RoutTable[p].iHop=itemphopN; 
						    RoutTable[p].NextNode=sendName; 
						    RoutTable[p].node1 =arr[itemp+1]; 
							RoutTable[p].node2 =arr[itemp+2]; 
							RoutTable[p].node3 =arr[itemp+3]; 
							RoutTable[p].node4 =arr[itemp+4]; 
							RoutTable[p].node5 =arr[itemp+5]; 
							RoutTable[p].iPort=iport; 
							RoutTable[p].iAge=0;						 
									 
						}//if 
								 
					}//for 
								 
				}//if  
		} 
	} 
 
}