MFC实现简单的聊天功能

本文介绍如何利用MFC与WinSock库构建一个简易的即时通信软件,模拟即时聊天应用的功能,包括登陆、上线和消息传递。实验分为服务端和客户端两部分,服务端负责用户数据配置,客户端则提供类似QQ的交互体验。
摘要由CSDN通过智能技术生成

设计目标:

2.设计二  简单的即时通信软件(6学时实验)

目的与要求: 利用WinSock进行点对点通信,工作机制模仿即时通信软件的基本功能,登陆,上线,传递信息等等。分为客户部分和服务器部分两块,客户部分类似一般通信软件例如QQ,服务器部分主要提供客户端用户基本数据配置。

服务端代码:

#include <WinSock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h> 
#include <string>
#include <sstream>
#pragma comment(lib,"pthreadVC2.lib")
#pragma comment(lib,"ws2_32.lib")
#include<iostream>
using namespace std;
/*void* recv1(SOCKET sockConn)
{  char recvBuf[10000];
memset(recvBuf, 0, sizeof(recvBuf));
//接收数据
while(true){

int nRecv = ::recv(sockConn, recvBuf, sizeof(recvBuf), 0);
cout<<endl;
if(nRecv>0)cout<<"他说:"<<recvBuf<<endl;
else break;}
}*/
SOCKET sockConn[10];
char password[] = "123456";	
int pass = 0;
const int nl = 100;
string user[nl] = { "123","456","789","张三" };
string pw[nl] = { "111","456","789","张三" };
int online[nl] = {0,0,0};//判断是否在线的数组
int match[nl] = {-1,-1,-1};//表示第i个用户名匹配的是第几个套接字
int find(string a[], string b)
{
	bool exist = false;
	for (int j = 0; j<nl; j++)
	{
		if (a[j] == b)
		{
			exist = true;
			return j;
		}
	}
	if (!exist)
		return -1;
}
int find1(SOCKET sock)
{
	for (int i = 0; i < 10; i++)
	{
		if (sock == sockConn[i])
		{
			return i;
			break;
            
		}
	}
	return -1;
}
int finds(string s)//根据用户名找到对应的套接字
{
	int index = find(user,s);
	if (index >= 0)
		return match[index];
	else
		return -1;
}
int  findu(SOCKET sock )//根据套接字找用户名在数组中的位置
{
	int index = find1(sock);
	for (int i = 0; i < nl; i++)
	{
		if (match[i] == index)
			return i;
	}
	return -1;
}
int nul_index(string a[])//查找string数组的空位,以便于用户注册的插入
{
	for (int i = 0; i < nl; i++)
	{
		if (a[i].empty())
			return i;
	}
	return nl;//没有空位,注册已满
}
void* recv1(void* args)
{
	char recvBuf[10000];
	char users[1000];
	char pws[1000];
	//接收数据
	bool success = false;//判断是否登录成功 
	int id1 = (unsigned int)pthread_getw32threadid_np(pthread_self()) / 2;
	SOCKET sockConn1 = *((SOCKET*)args);//建立套接字
	memset(recvBuf, 0, sizeof(recvBuf));
	int rel = 0;
	rel = recv(sockConn1, recvBuf, sizeof(recvBuf), 0);
	if (rel<0)
		cout << "接受失败\n";
	cout << rel<<" "<<recvBuf<<endl;
	send(sockConn1, "ack", sizeof(recvBuf),0);
	//cout<<recvBuf<<endl;
	if (strcmp(recvBuf, "1") == 0)//客户端选择登录 
	{
		cout << "选择登录服务\n";
		memset(users, 0, sizeof(users));
		rel = recv(sockConn1, users, sizeof(users), 0);
		if (rel<0)//接受用户名 
			cout << "recv failed";
		cout <<rel<<" "<< users << endl;
		send(sockConn1, "ack", sizeof(recvBuf),0);
		int index = find(user, users);//判断能否找到用户名 
		int sockNum = find1(sockConn1);
		if (index != -1)//找到用户名      
		{
			if (online[index] == 0)
			{

				cout << "找到用户名" << endl;
				memset(pws, 0, sizeof(pws));
				if (recv(sockConn1, pws, sizeof(pws), 0) < 0)//接受密码 
					cout << "recv failed";
				cout << pws << endl;
				if (pws == pw[index])//密码正确 
				{   
					online[index] = 1;
					success = true;
					match[index] = sockNum;
					if (send(sockConn1, "密码正确", sizeof(recvBuf), 0) < 0)
					{
						cout << "发送失败";
					}
				}
				else//密码错误 
				{
					send(sockConn1, "密码错误", sizeof(recvBuf), 0);
				}
			}
			else 
			{
				memset(pws, 0, sizeof(pws));
				if (recv(sockConn1, pws, sizeof(pws), 0)<0)//接受密码 
					cout << "recv failed";
				if (send(sockConn1, "该用户已存在", sizeof(recvBuf), 0)<0)
					cout << "发送失败";
			}
		}
		if (index == -1)//未找到用户名 
		{
			memset(pws, 0, sizeof(pws));
			if (recv(sockConn1, pws, sizeof(pws), 0)<0)//接受密码 
				cout << "recv failed";
			if (send(sockConn1, "用户名不存在", sizeof(recvBuf), 0)<0)
					cout << "发送失败";
		}
		if (success)
		{
			char buf[1000];
			int id = find1(sockConn1);
			int n = findu(sockConn1);
			const char*p=user[n].data();
			//user[n].copy(p, 40, 0);//这里5,代表复制几个字符,0代表复制的位置  
			//*(p + 40) = '\0';//要手动加上结束符

			if (id >= 1)
			{
				for (int j = 1; j < id + 1; j++)//好友上线功能 
				{

					if (send(sockConn[j - 1], p, sizeof(p), 0) < 0) //,sizeof(buf),0)<0)
						cout << "send failed";
					if (send(sockConn[j - 1], "已上线", sizeof(buf), 0) < 0)
						cout << "send failed";
				}
			}
			while (true)
			{
				memset(recvBuf, 0, sizeof(recvBuf));
				recv(sockConn1,recvBuf,sizeof(recvBuf),0);//接受要发送的用户名
				int index = find(user,recvBuf);//查找要发送用户名的位置
				if(strcmp(recvBuf, "all") == 0)//实现群发
				{
					memset(recvBuf, 0, sizeof(recvBuf));
					recv(sockConn1, recvBuf, sizeof(recvBuf), 0);
					for (int i = 0; i < nl; i++)
					{
						if (online[i] == 1&&i!=findu(sockConn1))
						{
							string a = user[n] + ": ";
							const char* pp = a.data();
							sockNum = finds(user[i]);
							if (send(sockConn[sockNum], pp, sizeof(pp), 0) < 0) //,sizeof(buf),0)<0)
								cout << "send failed";
							send(sockConn[sockNum], recvBuf, sizeof(recvBuf), 0);
						}
					}
				}
				else
				{
					if (strcmp(recvBuf, "退出") == 0)//用户选择退出
					{

						int i 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值