网络聊天室的UDP实现以及数据库

这篇具有很好参考价值的文章主要介绍了网络聊天室的UDP实现以及数据库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

网络聊天室UDP实现

服务器端:

头文件:

#include <myhead.h>
 
//定义客户信息结构体
typedef struct magtye
{
	char type;            //消息类型
	char name[100];         //客户姓名
	char text[1024];  //客户发送聊天信息
}msg_t;
 
//定义结构体存储每个客户端的ip地址和端口号
typedef struct IP_PORT
{
	struct sockaddr_in cin;//地址信息
	struct IP_PORT *next;//
 
}*addrlist;
 
void usr_login(int sfd,msg_t msg,addrlist *head,struct sockaddr_in cin);
void usr_chat(int sfd,msg_t msg,addrlist head,struct sockaddr_in cin);
void usr_quit(int sfd,msg_t msg,addrlist *head,struct sockaddr_in cin);
 

主函数:

#include"head.h"
int main(int argc, const char *argv[])
{
	//创建套接字
	int sfd=-1;
	sfd=socket(AF_INET,SOCK_DGRAM, 0);
	if(sfd==-1)
	{
		perror("socket error");
		return -1;
	}
	//将端口号快速重用
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
	{
		perror("setsockopt error");
		return -1;
	}
 
	//服务器进行绑定
	//(1)、从终端获取端口号和地址
	char SER_IP[100];
	int SER_PORT;
	printf("请输入服务器ip地址和端口号:");
	scanf("%s %d",SER_IP,&SER_PORT);
	getchar();//吸收垃圾字符
 
	//(2)、填充服务器地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;           //地址族
	sin.sin_port=htons(SER_PORT);    //端口号
	sin.sin_addr.s_addr=inet_addr(SER_IP);  //IP地址      	
	socklen_t sin_len=sizeof(sin);
	//(3)、绑定
	if(bind(sfd,(struct sockaddr*)&sin,sin_len)==-1)
	{
		perror("bind error");
		return -1;
	}
	//定义客户端网络信息结构体
	struct sockaddr_in cin;
	socklen_t cin_len=sizeof(cin);
 
	msg_t msg;//定义客户发送消息的机构体变量
 
	//创建父子进程处理不同的操作
	int pid=fork();
	if(pid==-1)
	{
		perror("fork error");
		return -1;
	}
	if(pid==0)//字进程实现服务器接收消息类型
	{
		addrlist head=NULL;//链表头指针;
		while(1)
		{
			memset(&msg,0,sizeof(msg));
			memset(&cin,0,sizeof(cin));
			//接收客户端发来的信息,并判断属于哪种消息类型
			recvfrom(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&cin,&cin_len);
			switch(msg.type)
			{
			case 'L':    //该消息类型代表新用户上线
				{
					//创建新节点保存新用户的ip地址和端口号				
					//向其他在线的用户发送新用户上线通知
					usr_login(sfd,msg,&head,cin);
 
				}break;
			case 'C':   //该消息类型代表一个用户发送消息给其他用户
				{
					usr_chat(sfd,msg,head,cin);
				}break;
			case 'Q':   //该消息类型代表一个用户下线
				{
					usr_quit(sfd,msg,&head,cin);
				}break;
			}
		}
	}
	else if(pid>0)//父进程实现服务器对客户端发送消息
	{
		strcpy(msg.name,"服务器消息");
		msg.type='C';
		while(1)
		{
			memset(msg.text,0,sizeof(msg.text));
			fgets(msg.text,sizeof(msg.text),stdin);
			msg.text[strlen(msg.text)-1]='\0';
			sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sin_len);
			if(strcmp(msg.text,"服务器下线")==0)
			{
				sleep(1);
				break;
			}
		}
		kill(pid,SIGKILL);//服务器下线杀死子进程
	}
	wait(NULL);
	//关闭套接字
	close(sfd);
	return 0;
}

自定义函数:

#include"head.h"
//用户登录操作函数
void usr_login(int sfd,msg_t msg,addrlist *head,struct sockaddr_in cin)
{
	//1、创建新节点
	addrlist s=(addrlist)malloc(sizeof(addrlist));
	s->next=NULL;
	//存储新用户的ip地址和端口号
	printf("%s : %d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
	s->cin=cin;
	s->next=*head;
	*head=s;
	//2、遍历链表将新用户上线消息发送给其他在线用户
	addrlist p=*head;
	while (p!=NULL)
	{
		if(p->cin.sin_port!=cin.sin_port)
		{
			sendto(sfd, &msg, sizeof(msg),0,(struct sockaddr *)&(p->cin), sizeof(p->cin));
		}
		p=p->next; //后移
	}
	printf("%s:%s\n",msg.name, msg.text);
 
}
 
//用户聊天操作函数
void usr_chat(int sfd,msg_t msg,addrlist head,struct sockaddr_in cin)
{
	addrlist p=head;
	while (p!=NULL)
	{
		if(p->cin.sin_port!=cin.sin_port)
		{
			sendto(sfd, &msg, sizeof(msg),0,(struct sockaddr *)&(p->cin), sizeof(p->cin));
		}
		p=p->next; //后移
	}
 
}
//用户退出操作函数
void usr_quit(int sfd,msg_t msg,addrlist *head,struct sockaddr_in cin)
{
	printf("%s:%s\n",msg.name, msg.text);
	addrlist p=*head;
	addrlist del=NULL;
	while (p!=NULL)
	{
		if(p->cin.sin_port!=cin.sin_port)  //向其他用户发送某个用户下线消息
		{
			sendto(sfd, &msg, sizeof(msg),0,(struct sockaddr *)&(p->cin), sizeof(p->cin));
			del=p;
			p=p->next;
		}
		else
		{
			sendto(sfd, &msg, sizeof(msg),0,(struct sockaddr *)&(p->cin), sizeof(p->cin));//向发出下线消息的用户回复消息
			if (del==NULL) 
			{
				*head=p->next;
			} 
			else 
			{
				del->next=p->next;
			}
			free(del);
			del=NULL;
			break;
		}
	}
}

客户端:

#include <myhead.h>
 
//定义客户信息结构体
typedef struct magtye
{
	char type;            //消息类型
	char name[100];         //客户姓名
	char text[1024];  //客户发送聊天信息
}msg_t;
 
int main(int argc, const char *argv[])
{
	//创建套接字
	int cfd=-1;
	cfd=socket(AF_INET, SOCK_DGRAM, 0);
	if(cfd==-1)
	{
		perror("socket error");
		return -1;
	}
	//将端口号快速重用
	int reuse=1;
	if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
	{
		perror("setsockopt error");
		return -1;
	}
 
	//(1)、从终端获取端口号和地址
	char SER_IP[100];
	int SER_PORT;
	printf("请输入服务器ip地址和端口号:");
	scanf("%s %d",SER_IP,&SER_PORT);
	getchar();//吸收垃圾字符
 
	//(2)、填充服务器地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;           //地址族
	sin.sin_port=htons(SER_PORT);    //端口号
	sin.sin_addr.s_addr=inet_addr(SER_IP);  //IP地址   
	socklen_t sin_len=sizeof(sin);
	msg_t msg;
 
	//客户端上线发送消息
	printf("请输入用户名:");
	fgets(msg.name,sizeof(msg.name),stdin);
	msg.name[strlen(msg.name)-1] = '\0';
	strcpy(msg.text,"已上线");
	msg.type='L';
	sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sin_len);
 
	//创建多进程进行收发消息操作
	int pid=fork();
	if(pid==-1)
	{
		perror("fork error");
		return -1;
	}
	 if(pid>0)//父进程进行读取消息
	{
		while(1)
		{
			recvfrom(cfd,&msg,sizeof(msg),0,NULL,NULL);
			if(strcmp(msg.text,"退出群聊")==0)    //用户自己下线
			{
				break;
			}
			printf("[%s]: %s\n", msg.name, msg.text);
			if(strcmp(msg.text,"服务器下线")==0) //服务器让客户端下线
			{
				kill(pid,SIGKILL);
				break;
			}
		}
	}
	else if(pid==0)//子进程发送消息
	{
		while(1)
		{
			memset(msg.text,0,sizeof(msg.text));
			fgets(msg.text,sizeof(msg.text),stdin);//在终端获取聊天信息
			msg.text[strlen(msg.text)-1]='\0';
			if(strcmp(msg.text, "下线")==0)
			{
				msg.type='Q';
				strcpy(msg.text, "退出群聊");
			}
			else
			{
				msg.type='C';
			}
			sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sin_len);
			if(strcmp(msg.text,"退出群聊")==0)
			{
				break;
			}
		}
		exit(EXIT_SUCCESS);
	}
	//关闭套接字回收子进程资源
	wait(NULL);   //阻塞回收子进程资源
	close(cfd);
	return 0;
}
 

思维导图:

网络聊天室的UDP实现以及数据库,算法文章来源地址https://www.toymoban.com/news/detail-842041.html

到了这里,关于网络聊天室的UDP实现以及数据库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux 基本语句_16_Udp网络聊天室

    服务端代码: 客户端代码: 总体效果是客户上线状态、退出状态、发送的消息都能通过广播,将信息发送给所有在线客户端,服务端能接收并显示所有客户端发送的消息,且也具备广播能力 服务端: 服务端创建了一个链表,这个链表中的每个节点是专用于储存客户端的ip地

    2024年02月04日
    浏览(40)
  • 计算机网络 TCP/UDP程序开发网络聊天室

    TCP/UDP程序开发 开发TCP/UDP协议应用程序,掌握网络应用程序的工作原理。通过该实验,深入理解UDP和TCP协议的异同点,了解网络协议的工作过程,学会网络通信编程的基本方法,能够编制网络应用程序。 (1)了解和掌握“基于UDP-面向无连接的应用程序/基于TCP-面向连接的

    2024年02月05日
    浏览(86)
  • 基于Linux系统聊天室增加数据库sqlite功能实现(08)

    全部掌握后,开始进入本篇。 为了方便编译,现在我们将前面文章的代码结构做如下调整。 最终增加了数据的文件目录如下: clean.sh  用于清除临时文件 gcc.sh  用于编译整个工程 服务端代码放置到chat_server目录下;客户端代码放置到chat_client目录下; 数据库相关代码放在

    2024年02月07日
    浏览(44)
  • 【嵌入式学习】网络通信基础-项目篇:简单UDP聊天室

    源码已在GitHub开源:0clock/LearnEmbed-projects/chat 客户端功能: 上线发送登录的用户名[yes] 发送消息和接收消息[yes] quit退出 服务器端功能: 统计用户上线信息,放入链表中[yes] 接收用户信息并给其他用户发送消息[yes] 服务器也支持给所有用户群发消息[yes] 接收下线提醒

    2024年01月25日
    浏览(60)
  • [Socket]Python用UDP协议建立带有私聊功能的网络聊天室-建立聊天工具

    前些天实习面试的时候被面试官问到Socket编程的问题,即“Socket创建和释放的具体过程是什么”,当时答不上来,似乎是涉及到发送和接收缓冲区的问题。由于自己在Socket编程这一块知识较为薄弱,于是写下这篇文章,当作复习下Socket编程知识。 首先,该实验是我在大三上学

    2024年02月03日
    浏览(47)
  • C语言实现--基于UDP的多人在线聊天室

    目录 实现功能 实现思想 实现代码(部分及详解) 服务端部分代码 客户端部分代码 实现效果 项目中出现的问题和解决方法 项目整体代码展示 代码优化思路 服务端代码 客户端代码 服务端可以同时连接多个客户端; 新的客户端连接服务端时,可以在服务端显示自己的名字并

    2024年02月04日
    浏览(60)
  • UDP聊天室

    1.头文件 2.服务器 3.客户端 4.makefile 5.结果

    2024年02月10日
    浏览(46)
  • UDP套接字的通信(实现英汉互译/程序替换/多线程聊天室/Windows与Linux通信)

    我们在客户端发英文,服务端做翻译工作,让翻译好的中文再次发给我们的客户端,然后打印出来。 翻译的操作 创建一个txt文件里面包含英汉互译的数据 dict.txt 对txt中的数据进行操作 分割函数 将英汉通过冒号分开。 将文件数据插入map里面 重新加载文件 通过捕捉2号(ctrl

    2024年02月11日
    浏览(34)
  • 【Linux】基于UDP协议的“聊天室”

    目录 预备知识 基本思路 服务端设计 重要接口详解 服务端核心代码 服务端运行代码 客户端设计 UDP协议(User Datagram Protocal用户数据报协议) 传输层协议 无连接 不可靠传输 面向数据报 如下是我们设计的一个简单的“聊天室”的大致框架图:         “聊天室”分为两个角

    2024年02月20日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包