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

📄 chatnet.cpp

📁 TCP/IP and Windows 95. Sources from DDJ article
💻 CPP
字号:
// Chatnet.cpp 
// CChatnet implementation file

#include "chatnet.h"
#include "string.h"
#include "resource.h"

CChatNet::CChatNet()
{
}
/* Lists returns a pointer to the address list */
CAddrList* CChatNet::GetAddressList()
{
return	m_AddrList;
}
    
/* initializes the network and binds to the protocol, sets up the messaging,
gets the user name, sets the address list and sets the channel to 1 */
BOOL CChatNet::InitNetwork(HWND hWnd)
{   
	
	if(!InitNet())
		{
	    TRACE("Failed to activate Network\n"); 
	    return FALSE;
    }
	if(!SetProtocol(hWnd))
		{
		TRACE("Failed to set protocol\n");
		return FALSE;
		}         
		   
		
	
	CAddr*	MyAddr = new CAddr;
	if(MyAddr == NULL)
		{
		return FALSE;
		}
	m_AddrList = new CAddrList;		
	m_AddrList->AddHead(MyAddr);
	
	m_Channel = 1;
    return TRUE;
}    

/* sends a packet greeting a new user who just entered the IPC chat world.
the user name is then added to the user list */
BOOL CChatNet::WelcomeUser(LPSTR Name,LPSTR IpAddr, CHATPACKET Message)
{ 
	CAddr *addr = new CAddr;
	if(addr == NULL)
		{    
		return FALSE;
		}       
            
    SendChatPacket(IpAddr, Name, REPLYBROADCAST,NULL);
	addr->SetAddress(Message.Name,IpAddr);
	if(!Duplicate(addr))
		m_AddrList->Insert(addr);
	else
		delete [] addr;
	return TRUE;
            
}

/* This adds a user who just enetered the net to the usernet */
BOOL CChatNet::ReplyBroadcast(LPSTR Name,LPSTR IpAddr, CHATPACKET Message)
{  
	CAddr *addr = new CAddr;
	if(addr == NULL)
		{    
		return FALSE;
		}       
    
	addr->SetAddress(Message.Name,IpAddr);
	if(!Duplicate(addr))
		{
		m_AddrList->Insert(addr);
		}
	else
		delete [] addr;
		
	return TRUE;
}  


/* searches to see if this address structure already exists in the user list */
BOOL CChatNet::Duplicate(CAddr *myAddr)
{                                            
	int counter = 0;
	CAddr *Addr;     
	POSITION	list;                 
	list = m_AddrList->GetHeadPosition();
	Addr = m_AddrList->GetNext(list);
	counter = m_AddrList->GetCount();
	if(counter>1)
		while(list != NULL)
			{	                                     
			Addr = m_AddrList->GetNext(list);
			if((strcmpi(myAddr->m_Name, Addr->m_Name) == 0) |
				(strcmpi(myAddr->m_Address,Addr->m_Address) == 0))
					return TRUE;
			}         
	return FALSE;		
}

/* sends a packet to alert the other workstations that our user name has changed */
BOOL CChatNet::NameUpdate(LPSTR IpAddr, CHATPACKET Message)
{                                            
	int counter = 0;
	CAddr *Addr;     
	POSITION	list;                 
	list = m_AddrList->GetHeadPosition();
	Addr = m_AddrList->GetNext(list);
	counter = m_AddrList->GetCount();
	if(counter>1)
		while(list != NULL)
			{	                                     
			Addr = m_AddrList->GetNext(list);
				if(lstrcmpi(IpAddr,Addr->m_Address) == 0)
					{
					lstrcpy(Addr->m_Name,Message.Name);
					return TRUE;
					}
			}         
	return FALSE;		
}


/* Deletes an address entry from the user entry */
BOOL CChatNet::DeleteUser(LPSTR IpAddr, CHATPACKET Message)
{                                            
	int counter = 0;
	CAddr *Addr;     
	POSITION	list,oldlist;
	list = m_AddrList->GetHeadPosition();
	Addr = m_AddrList->GetNext(list);
	counter = m_AddrList->GetCount(); 
	oldlist = list;
	if(counter>1)
		while(list != NULL)
			{
			Addr = m_AddrList->GetNext(list);	                                     
			if(lstrcmpi(IpAddr,Addr->m_Address) == 0)
				{ 
				m_AddrList->RemoveAt(oldlist);
				delete Addr;
				return TRUE;
				} 
			oldlist = list;
			}         
	return FALSE;		
}

/* changes the channel to the user selected channel */
void CChatNet::SetChannel(UINT Channel)
{               
	m_Channel = Channel;
}

/* attaches the application to the winsock.dll,
determines if the winsock.dll is a valid version,
and makes sure that there are enough sockets available */
BOOL CChatNet::InitNet(void)
{
	if(WSAStartup(SOCKET_VERSION, &m_wsaData))
		{
		TRACE("Couldn't find the winsock.dll\n");
		return FALSE;
		}        
		
	if(m_wsaData.wVersion < SOCKET_VERSION)
	    {
	    TRACE("Winsock too old a rev\n");
	    return FALSE;
	    }        
	    
	if(m_wsaData.iMaxSockets < SOCKETS)
		{
		TRACE("Not enough sockets available\n");
		return FALSE;
		}                         
return TRUE;		
}

/* gracefully closes the winsock.dll and shuts down the network */
BOOL CChatNet::CloseNet(void)
{     
	closesocket(m_Socket);
	ClearList();
return TRUE;
} 

/* sets the protocol to communicate to the network with,
sets the message handler, activates the socket, and binds the 
protocol to the socket */
BOOL CChatNet::SetProtocol(HWND hWnd)
{   
	m_Socket=socket(PF_INET,SOCK_DGRAM,0);

	if(m_Socket == INVALID_SOCKET)
		{
		TRACE("Cannot snag socket\n");
		return FALSE;
		}

	m_station = getservbyname("echo","udp"); 
	m_station->s_port = htons(IPC_PORT);  
	if(m_station == NULL)
		{
		TRACE("Can't get service port address\n");
		return FALSE;
		}		
			
	source_addr.sin_family = AF_INET;
	source_addr.sin_addr.s_addr = INADDR_ANY;
	source_addr.sin_port = m_station->s_port;
	
	if(bind(m_Socket, (LPSOCKADDR) &source_addr, sizeof(source_addr)) == SOCKET_ERROR)
		{
		TRACE("Cannot bind to socket\n");
		return FALSE;
		} 
		
	if((WSAAsyncSelect(m_Socket,hWnd,SOCKET_MESSAGE, FD_READ | FD_WRITE)) ==
		SOCKET_ERROR)
		{
		TRACE("Unable to set wsaasync\n");
		return FALSE;
		}
    

	return TRUE;
} 


/* returns the size of a message */
UINT CChatNet::MessageLen(void)
{                         
	return sizeof CHATPACKET;
}	

/* receives a chat packet, call only if there really 
is data waiting on the socket */
UINT CChatNet::RecChatPacket(LPSTR *lpstrSourceAddress,CHATPACKET *Message)
{
	int incoming;                                      
	SOCKADDR_IN	inaddr;                                                      
	int addrlen = sizeof(inaddr);
	incoming = recvfrom(m_Socket,(char *) Message, MessageLen(),
						0, (PSOCKADDR) &inaddr,&addrlen); 
  	
  	*lpstrSourceAddress = inet_ntoa(inaddr.sin_addr);  
    
	if(incoming == -1)
		{
		incoming = 0;
		incoming = WSAGetLastError() + 2000;
		}
		
	return incoming;
}

/* returns the last network event message */
WORD CChatNet::NetEvent(LPARAM lParam)
{
return WSAGETSELECTEVENT(lParam);
} 

/* calculates the correct broadcast address based upon the workstations
ip address */
BOOL CChatNet::SendBroadcast(LPSTR UserName)
{ 
	
	int buflen = 50;
    LPHOSTENT MyHost;
    char *buf = new char[100];
    UINT myerror;
	if ((myerror = gethostname(buf,buflen)) == 0)     
		{
  		MyHost = gethostbyname(buf);
  		}
  	else                    
  		{
  		myerror = WSAGetLastError();
  		return FALSE;               
  		}
  		
 	if (MyHost==NULL)
  		return FALSE;		   

	unsigned char octet[4];
	octet[0] = MyHost->h_addr[0];
	
	if(octet[0] < 191)
		{
		octet[1] = MyHost->h_addr[1];	
		octet[2] = '\xff';
		}
	if(octet[0] < 127)
		octet[1] = '\xff';			           
    octet[3] = '\xff';    


	sprintf(buf,"%d.%d.%d.%d",octet[0],octet[1],octet[2],octet[3]);
	 
	if((SendChatPacket(buf,UserName, BROADCAST,NULL)) > 12000)
		{ 
	    delete [] buf;
		return FALSE;
		}            

		
delete [] buf;
return TRUE;			
}

BOOL CChatNet::SendListPacket( LPCSTR UserName, UINT Mode, LPSTR Message)
{
	int counter = 0;
	CAddr *Addr;     
	POSITION	list;                 
	list = m_AddrList->GetHeadPosition();
	Addr = m_AddrList->GetNext(list);
	counter = m_AddrList->GetCount();
	
	if(counter)
	while(list != NULL)
		{	
		Addr = m_AddrList->GetNext(list);
		SendChatPacket(Addr->m_Address,UserName, Mode, Message);
		}         
	return TRUE;

}   

UINT CChatNet::SendChatPacket(LPCSTR lpstrDestination, LPCSTR UserName, UINT Mode, LPSTR Message)
{   
	
	CHATPACKET CP;
	CString Mesg;
	
    lstrcpy(CP.Name, UserName);
	CP.Mode = Mode;                        
	CP.Channel = m_Channel;
	switch(Mode)
		{
		case BROADCAST:
			Mesg.LoadString(IDS_ENTERING);
			lstrcpy(CP.Message,Mesg.GetBuffer(Mesg.GetLength()));
			break;
		case REPLYBROADCAST:
			Mesg.LoadString(IDS_REPLYBROADCAST);
			lstrcpy(CP.Message,Mesg.GetBuffer(Mesg.GetLength()));
			break;
			
		case NAMEUPDATE:
	 		Mesg.LoadString(IDS_NAMECHANGE);
			lstrcpy(CP.Message,Mesg.GetBuffer(Mesg.GetLength()));
	 		break;	

		case LEAVINGGROUP:
			Mesg.LoadString(IDS_LEAVINGGROUP);
			strcpy(CP.Message,Mesg.GetBuffer(Mesg.GetLength()));
        	break;
		case MESSAGE:
			lstrcpy(CP.Message,Message);
			break;
		}
		
	CP.MessageLen = strlen(CP.Message);
	
	
	SOCKADDR_IN	dest_addr;
	
	dest_addr.sin_family = AF_INET;
	dest_addr.sin_addr.s_addr = inet_addr(lpstrDestination);
	dest_addr.sin_port = m_station->s_port;
	return	sendto(m_Socket, (char *) &CP,MessageLen(),0,
				  (PSOCKADDR) &dest_addr,sizeof(dest_addr));
				  
}



BOOL CChatNet::ClearList(void)
{                                            
	int counter = 0;
	CAddr *Addr;     
	POSITION	list,oldlist;
	list = m_AddrList->GetHeadPosition();
	Addr = m_AddrList->GetNext(list);
	counter = m_AddrList->GetCount(); 
	oldlist = list;
	while(list != NULL)
		{
		Addr = m_AddrList->GetNext(list);	                                     
		m_AddrList->RemoveAt(oldlist);
		oldlist = list;
		delete Addr;
        }         
	delete m_AddrList;
	return TRUE;
}

⌨️ 快捷键说明

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