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

📄 p2pserver.c

📁 很好用的udp穿透nat的程序代码,是两个在nat后的pc可以直接通讯。
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "proto.h"
#include "Exception.h"
UserList ClientList;

int  mksock(int type)
{
	int sock;
	sock = socket(AF_INET, type, 0);
 	if (sock < 0)
 	{
        	printf("create socket error");
 	}
 	return sock;
}

stUserListNode GetUser(char *username)
{
	for(UserList::iterator UserIterator=ClientList.begin();
      		UserIterator!=ClientList.end();
       		++UserIterator)
 	{
  		if( strcmp( ((*UserIterator)->userName), username) == 0 )
   			return *(*UserIterator);
 	}
 	throw Exception("not find this user");
}
int main(int argc, char* argv[])
{
  	int  PrimaryUDP;
  	int nResult;
  	sockaddr_in sender;
  	stMessage recvbuf;
   	size_t  dwSender;
   	int ret;
    	int messageType;
      	stUserListNode *currentuser;
        in_addr tmp;
      	stP2PMessage transMessage;
	int nodecount;
      	int command = GETALLUSER;
	try
	{
  		PrimaryUDP = mksock(SOCK_DGRAM);
  		sockaddr_in local;
  		local.sin_family=AF_INET;
  		local.sin_port= htons(SERVER_PORT); 
  		local.sin_addr.s_addr = htonl(INADDR_ANY);
  		nResult=bind(PrimaryUDP,(sockaddr*)&local,sizeof(sockaddr));
  		if(nResult<0)
   			throw Exception("bind error");
  		memset(&recvbuf,0,sizeof(stMessage));
  		for(;;)
  		{
   			dwSender = sizeof(sender);
   			ret = recvfrom(PrimaryUDP, (char *)&recvbuf, sizeof(stMessage), 0, (sockaddr *)&sender, &dwSender);
   			if(ret <= 0)
   			{
    				printf("recv error");
    				continue;
   			}
   			else
   			{
    				messageType = recvbuf.iMessageType;
    				switch(messageType)
				{
    					case LOGIN:
					{
      						printf("has a user login : %s\n", recvbuf.message.loginmember.userName);
      						currentuser = new stUserListNode();
      						strcpy(currentuser->userName, recvbuf.message.loginmember.userName);
      						currentuser->ip = ntohl(sender.sin_addr.s_addr);
      						currentuser->port = ntohs(sender.sin_port);
      
      						ClientList.push_back(currentuser);      
						nodecount = (int)ClientList.size();

      						sendto(PrimaryUDP, (const char*)&nodecount, sizeof(int), 0, (const sockaddr*)&sender, sizeof(sender));
      						for(UserList::iterator UserIterator=ClientList.begin();
        						UserIterator!=ClientList.end();
        						++UserIterator)
      						{
       							sendto(PrimaryUDP, (const char*)(*UserIterator), sizeof(stUserListNode), 0, (const sockaddr*)&sender, sizeof(sender)); 
      						}
      						break;
     					}
    					case LOGOUT:
     					{
      						printf("has a user logout : %s\n", recvbuf.message.logoutmember.userName);
      						UserList::iterator removeiterator = NULL;
      						for(UserList::iterator UserIterator=ClientList.begin();UserIterator!=ClientList.end();++UserIterator)
      						{
       							if( strcmp( ((*UserIterator)->userName), recvbuf.message.logoutmember.userName) == 0 )
       							{
        							removeiterator = UserIterator;
        							break;
       							}
      						}
      						if(removeiterator != NULL)
       							ClientList.remove(*removeiterator);
      						break;
     					}
    					case P2PTRANS:
     					{
      						printf("%s wants to p2p %s\n",inet_ntoa(sender.sin_addr),recvbuf.message.translatemessage.userName);
      						stUserListNode node = GetUser(recvbuf.message.translatemessage.userName);
      						sockaddr_in remote;
      						remote.sin_family=AF_INET;
      						remote.sin_port= htons(node.port); 
      						remote.sin_addr.s_addr = htonl(node.ip);
      						tmp.s_addr = htonl(node.ip);
      						printf("the address is %s,and port is %d\n",inet_ntoa(tmp), node.port);
      						transMessage.iMessageType = P2PSOMEONEWANTTOCALLYOU;
      						transMessage.iStringLen = ntohl(sender.sin_addr.s_addr);
      						transMessage.Port = ntohs(sender.sin_port);
                        
      						sendto(PrimaryUDP,(const char*)&transMessage, sizeof(transMessage), 0, (const sockaddr *)&remote, sizeof(remote));
      						break;
     					}
    
    					case GETALLUSER:
     					{
      						sendto(PrimaryUDP, (const char*)&command, sizeof(int), 0, (const sockaddr*)&sender, sizeof(sender));
      						nodecount = (int)ClientList.size();
      						sendto(PrimaryUDP, (const char*)&nodecount, sizeof(int), 0, (const sockaddr*)&sender, sizeof(sender));
      						for(UserList::iterator UserIterator=ClientList.begin();UserIterator!=ClientList.end();++UserIterator)
      						{
       							sendto(PrimaryUDP, (const char*)(*UserIterator), sizeof(stUserListNode), 0, (const sockaddr*)&sender, sizeof(sender)); 
      						}
      						break;
     					}
    				}
   			}
 	 	}
	}
 	catch(Exception &e)
 	{
  		printf(e.GetMessage());
 		 return 1;
 	}
	return 0;
}

⌨️ 快捷键说明

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