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

📄 chatclient.cpp

📁 一个控制台console的聊天程序
💻 CPP
字号:
#include <winsock2.h>
#include <iostream.h>
#include "ChatStruct.h"
#pragma comment(lib, "wsock32.lib")

SOCKET sock;                   //socket
sockaddr_in addrto;            //发往的地址	
char loginName[20];

char sendMsg[1024];				//发送缓冲区

HANDLE thread_recvHandle;				//定义接收线程句柄
void RecvThread();						//接收线程

bool login();								//登陆
void sendMessage(char *buf,int length);		//发送聊天消息
void viewList();							//查看用户列表
bool exitChatRoom();						//退出聊天室


void main()
{	
	//1.启动SOCKET库,版本为2.0
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;	
	wVersionRequested = MAKEWORD( 2, 0 );	
	err = WSAStartup(wVersionRequested, &wsaData );
	if ( err != 0 ) 
	{
		cout<<"Socket2.0初始化失败,Exit!";
		return;
	}	
	if ( LOBYTE( wsaData.wVersion ) != 2 ||	HIBYTE( wsaData.wVersion ) != 0 ) 
	{
		WSACleanup( );
		return; 
	}
	
	//2.创建socket,
	sock = socket(
		AF_INET,           //internetwork: UDP, TCP, etc
		SOCK_DGRAM,        //SOCK_DGRAM说明是UDP类型
		0                  //protocol
		);
	
	if (sock == INVALID_SOCKET ) {
		cout<<"Socket 创建失败,Exit!";
		return;
	}
	
	//3.设置发往的地址
	memset(&addrto,0,sizeof(addrto));
	addrto.sin_family=AF_INET;
	addrto.sin_addr.s_addr=inet_addr("127.0.0.1");//此处应填服务器IP	
	addrto.sin_port=htons(5656);				  //端口号必须和服务器绑定的端口号一致
	
	int nlen=sizeof(addrto);
	unsigned int uIndex = 1;
	
	while (!login())
	{
		continue;
	}


	DWORD session_thread_id = 1;
	thread_recvHandle=CreateThread(0,
		0,
		(LPTHREAD_START_ROUTINE)RecvThread,
		0,
		0,
		&session_thread_id);


	while(true)
	{
		memset(sendMsg,0,1024);
		cin>>sendMsg;
		if (!strcmp(sendMsg,"list"))
		{
			viewList();
		}
		else if(!strcmp(sendMsg,"exit"))
		{
			if (exitChatRoom())
			{
				break;
			}
			else
			{
				cout<<"非安全退出..........."<<endl;
			}
		}
		else if(!strcmp(sendMsg,"help"))
		{
			cout<<"*********************************\n";
			cout<<"[list] 命令查看在线用户列表"<<endl;
			cout<<"[help] 命令查看帮助"<<endl;
			cout<<"[exit] 命令退出聊天室"<<endl;
			cout<<"*********************************\n";
		}
		else
		{
			sendMessage(sendMsg,strlen(sendMsg));
		}
	
	}
	Sleep(2500);

	if (!closesocket(sock)) 
	{
		WSAGetLastError();
		return;
	}
	if (!WSACleanup()) 
	{
		WSAGetLastError();
		return;
	}	
}


bool login()
{
	GramHead loginHead;
	unsigned char name[20];
	memset(name,0,20);
	cout<<"输入你登录聊天室的用户名:"<<endl;
	cin>>loginHead.USERNO;
	strcpy(loginName,loginHead.USERNO);
	loginHead.COMMAND=C_LOGIN;
	loginHead.LENGTH=1024;
	loginHead.COUNT=5;
	loginHead.NO=1;
	loginHead.PACKID=20;
	unsigned char *szMsg=new unsigned char[1024];
	memset(szMsg,0,1024);
	int nlen=sizeof(addrto);
	memcpy(szMsg,&loginHead,sizeof(GramHead));
	//	cout<<"要发送到的端口 "<<addrto.sin_port<<endl;
	if( sendto(sock,(const char *)szMsg,1024,0,(sockaddr*)&addrto,nlen)
		== SOCKET_ERROR )
		cout<<WSAGetLastError()<<endl;
	else
		cout<<"正在登陆,请稍后......"<<endl;
	delete szMsg;


	//接收到的SOCK地址
	sockaddr_in from;
	memset(&from,0,sizeof(from));
	
	int fromlength = sizeof(SOCKADDR);
	char *buf=new char[1024];
	Sleep(1000);
	recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr FAR *)&from,(int FAR *)&fromlength);
	GramHead loginBack;	//接收到的登陆返回包头
	memcpy(&loginBack,buf,sizeof(GramHead));
	if (loginBack.COMMAND==S_LOGIN)
	{
		cout<<"登陆成功,欢迎你来到**聊天室!"<<endl;
		delete buf;
	}
	else
	{
		delete buf;
		return false;
	}
	return true;
}


void sendMessage(char *buf,int length)
{
	GramHead sendHead;
	sendHead.COMMAND=C_MESSAGE;
	strcpy(sendHead.USERNO,loginName);

	unsigned char *szMsg=new unsigned char[1024];
	memset(szMsg,0,1024);
	int nlen=sizeof(addrto);
	memcpy(szMsg,&sendHead,sizeof(GramHead));
	memcpy(szMsg+sizeof(GramHead),buf,length);
	
	if( sendto(sock,(const char *)szMsg,1024,0,(sockaddr*)&addrto,nlen)
		== SOCKET_ERROR )
		cout<<WSAGetLastError()<<endl;
}



//接收线程
void RecvThread()
{
	//接收到的SOCK地址
	sockaddr_in from;
	memset(&from,0,sizeof(from));
	
	int fromlength = sizeof(SOCKADDR);
	char *buf=new char[1024];
	memset(buf,0,1024);
	Sleep(1000);
	while(1)
	{
		Sleep(1000);
		recvfrom(sock,buf,1024,0,(struct sockaddr FAR *)&from,(int FAR *)&fromlength);
		GramHead msgHead;	//接收到的登陆返回包头
		memcpy(&msgHead,buf,sizeof(GramHead));
		switch(msgHead.COMMAND)
		{
		case C_RECVMESSAGE:		//客户消息
			cout<<msgHead.USERNO<<" 说道:"<<buf+sizeof(GramHead)<<endl;
			break;
		case S_MESSAGE:			//系统消息
			cout<<"系统消息:"<<buf+sizeof(GramHead)<<endl;
			break;
		case S_USERLIST:
			cout<<"--------------------------------\n";
			cout<<"当前在线用户为:\n";
			cout<<buf+sizeof(GramHead);
			cout<<"--------------------------------\n"<<endl;
			break;
		case S_LOGOUT:
			cout<<":::::系统提示:::::"<<buf+sizeof(GramHead)<<" 离开了聊天室......"<<endl;
			break;
		case S_USERLOGIN:
			cout<<":::::系统提示:::::"<<buf+sizeof(GramHead)<<" 进入了聊天室!"<<endl;
			break;
		}
		memset(buf,0,1024);
	}
	delete buf;
}


void viewList()
{
	GramHead head;
	head.COMMAND=C_USERLIST;
	unsigned char *szMsg=new unsigned char[1024];
	memset(szMsg,0,1024);
	int nlen=sizeof(addrto);
	memcpy(szMsg,&head,sizeof(GramHead));
	
	if( sendto(sock,(const char *)szMsg,1024,0,(sockaddr*)&addrto,nlen)
		== SOCKET_ERROR )
		cout<<WSAGetLastError()<<endl;
	delete szMsg;
}


bool exitChatRoom()
{
	GramHead head;
	head.COMMAND=C_LOGOUT;
	unsigned char *szMsg=new unsigned char[1024];
	memset(szMsg,0,1024);
	int nlen=sizeof(addrto);
	memcpy(szMsg,&head,sizeof(GramHead));
	
	if( sendto(sock,(const char *)szMsg,1024,0,(sockaddr*)&addrto,nlen)
		== SOCKET_ERROR )
	{
		cout<<WSAGetLastError()<<endl;
		delete szMsg;
		return false;
	}
	delete szMsg;
	return true;
}

⌨️ 快捷键说明

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