如何搭建公共聊天室

搭建公共聊天室

一、聊天室介绍

    本聊天室主要运用了udp协议,应用于局域网范围之内,可以支持多个处于同一个局域网的主机在局域网内相互传递消息。本聊天室由一个服务器端和若干个客户端组成,由一台主机打开服务器端,其他主机通过udp协议连接服务器端的主机,并通过服务器端的主机将数据发送给其他主机。本聊天室可以完成检测用户的登录、聊天信息、退出与连接断开等四个主要功能。下面将介绍整个聊天室各项功能的搭建过程和网络搭建过程。

二、聊天室服务器端和客户端网络连接搭建过程

在这里插入图片描述

服务器端:

1)首先创建套接字;

int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

2)申请网络信息结构体;

struct sockaddr_in serveraddr;memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));//从终端获取服务器端口号serveraddr.sin_addr.s_addr = inet_addr(argv[1]);//从终端获取服务器ip地址socklen_t serveraddr_len = sizeof(serveraddr);

3)将套接字与网络信息结构体进行绑定;

bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len);

4)接收客户端发来的信息,向客户端反馈信息;

recvfrom(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&clientaddr, &clientaddr_len);//接收消息
sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&serveraddr, serveraddr_len)//向客户端发送消息

5)关闭套接字;

    close(sockfd);

客户端:1)首先创建套接字;

int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

2)申请网络信息结构体;

struct sockaddr_in serveraddr;memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));//从终端获取要连接的服务器端端口号serveraddr.sin_addr.s_addr = inet_addr(argv[1]);//从终端获取要连接的服务器端ip地址socklen_t serveraddr_len = sizeof(serveraddr);

3)将套接字与网络信息结构体进行绑定(这一步可以删去);

4)向服务器端发送的信息,接收服务器端反馈信息;

sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&serveraddr, serveraddr_len);//向服务器端发送信息
recvfrom(sockfd, &msg, sizeof(msg), 0, NULL, NULL);//接收服务器端发来的消息

5)关闭套接字

close(sockfd);

三、服务器端和客户端各项功能的设计与实现

在这里插入图片描述

1.聊天室功能设计:

聊天室需要实现的功能:

    有新用户登录,其他在线的用户可以收到登录信息;

    有用户群聊,其他在线的用户可以收到群聊信息;

    有用户退出,其他在线的用户可以收到退出信息;

    服务器可以发送系统信息。

整个聊天室大概思路:

  1)客户端登录之后,为了实现一边发送数据一边接收数据,可以使用多进程或者多线程;

  2)服务器既可以发送系统信息,又可以接收客户端信息并处理,可以使用多进程或者多线程;

  3) 服务器需要给多个用户发送数据,所以需要保存每一个用户的信息,使用链表来保存;

注:数据传输的时候要定义结构体,结构体中包含操作码、用户名以及数据;

2.聊天室功能实现:

服务器端:

//将接收信息的任务交给子线程
while(1){memset(&msg, 0, sizeof(msg));memset(&clientaddr, 0, sizeof(clientaddr));if(-1 == recvfrom(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&clientaddr, &clientaddr_len)){ERRLOG("recvfrom error");}printf("%8s : [%s]\n", msg.name, msg.txt);switch(msg.code){case 'L':do_login(clientaddr, phead, sockfd, msg);break;case 'C':do_chat(clientaddr, phead, sockfd, msg);break;case 'Q':do_quit(clientaddr, phead, sockfd, msg);break;}

用户登录功能:

//登录操作的函数
int do_login(struct sockaddr_in clientaddr, node_t *phead, int sockfd, msg_t msg){//先遍历链表 将登陆的消息发给所有在线用户node_t *ptemp = phead;while(ptemp->next != NULL){ptemp = ptemp->next;if(-1 == sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&(ptemp->c_addr), sizeof(ptemp->c_addr))){ERRLOG("sendto error");}}//将新登录的用户采用头插法插入到链表中node_t *pnew = NULL;create_node(&pnew);pnew->c_addr = clientaddr;pnew->next = phead->next;phead->next = pnew;return 0;
}

用户发送消息功能:

//群聊的函数
int do_chat(struct sockaddr_in clientaddr, node_t *phead, int sockfd, msg_t msg){//遍历链表,将群聊的数据发送给除了自己之外的所有人node_t *ptemp = phead;while(ptemp->next != NULL){ptemp = ptemp->next;if(memcmp(&clientaddr, &(ptemp->c_addr), sizeof(clientaddr))){if(-1 == sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&(ptemp->c_addr), sizeof(ptemp->c_addr))){ERRLOG("sendto error");}}}
}

用户退出功能:

int do_quit(struct sockaddr_in clientaddr, node_t *phead, int sockfd, msg_t msg){//将退出群聊的消息发给除了自己之外的所有在线用户//并且将自己在链表中删除node_t *ptemp = phead;while(ptemp->next != NULL){if(memcmp(&clientaddr, &(ptemp->next->c_addr), sizeof(clientaddr))){//不是自己,就发送数据ptemp = ptemp->next;if(-1 == sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&(ptemp->c_addr), sizeof(ptemp->c_addr))){ERRLOG("sendto error");}}else{//如果是自己,就将自己在链表中删除node_t *pdel = ptemp->next;ptemp->next = pdel->next;free(pdel);pdel = NULL;}}
}

客户端:

1.创建的用户先登录进入群聊并发送登录信息

msg.code = 'L';strcpy(msg.txt, "加入群聊");if(-1 == sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&serveraddr, serveraddr_len)){ERRLOG("sendto error");}

2.创建的用户在登录后发送信息并接收服务器端的信息

    子进程负责接收客户端发来的消息

        while(1){memset(&msg, 0, sizeof(msg));if(-1 == recvfrom(sockfd, &msg, sizeof(msg), 0, NULL, NULL)){ERRLOG("recvfrom error");}printf("%8s : [%s]\n", msg.name, msg.txt);}

    父进程负责发送信息,并检测客户端是否退出了聊天室,并将子进程终结在这里关闭客户端

while(1){msg.code = 'C';fgets(msg.txt, 128, stdin);msg.txt[strlen(msg.txt) - 1] = '\0';//判断是不是要退出if(!strcmp(msg.txt, "quit")){msg.code = 'Q';strcpy(msg.txt, "退出群聊");}if(-1 == sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&serveraddr, serveraddr_len)){ERRLOG("sendto error");}if(!strcmp(msg.txt, "退出群聊")){break;}}//先让子进程自杀kill(pid, SIGKILL);wait(NULL);close(sockfd);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/19179.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实战:向人工智能看齐用Docker部署一个ChatGPT

文章目录 前言鉴赏chatgpt环境要求开始搭建云安装docker从docker仓库拉取chatgpt-web镜像创建容器并运行chatgpt-web创建容器启动chatgpt-web访问自己的chatgpt 总结 前言 目前GPT-4都官宣步入多模态大型语言模型领域了,大佬竟然还没有体验GPT么。作为一个资深搬砖…

ChatGPT | Poe AI—体验多个不同 AI 人工智能对话模型

近日,随着ChatGPT等AI产品不断推陈出新,问答平台Quora现也开放新的AI聊天机器人应用Poe,可供用户随意访问。用户可以向它提出问题,Poe从多种AI聊天机器人处获取答案,包括ChatGPT背后母公司OpenAI以及Anthropic等其他公…

MySQL 8.0原理与实战一网打尽,甲骨文数据库专家硬刚5年之作

一、MySQL 8.0势在必行 据权威数据库技术排名网站DB-Engines今年4月的最新数据,MySQL是全球最流行的开源数据库,没有之一。在所有数据库排名中,MySQL仅次于Oracle,“屈居”亚军之位。但大家从截图中可以看出,MySQL与O…

嵌入式音视频疑惑汇总

小小的脑袋里,大大的疑问,该文是博主在工作中遇见问题后,主要面向chatGPT学习的记录笔记 1、bypass hdr 是什么? “Bypass HDR” 是指绕过高动态范围(HDR)功能的一种设置。HDR 是指一种显示技术&#xff0…

40岁程序员谈修bug的心态问题

【CSDN 编者按】于程序员而言,如果说写代码是一种能力的体现,那么解决问题的能力也同等重要,排查问题的能力或许能决定你的职业生涯走的有多远。因此,常有人戏言,程序员不是写代码,而是在写 bug。本文作者是…

一次查找分子级Bug的经历,过程太酸爽了

“Debugging is like trying to find a needle in a haystack, except the needle is also made of hay.” Debug调试就像是在大片的干草堆中找针一样,只不过针也是由干草制成的。 在软件开发的世界里,偶尔会出现一些非常隐蔽的 Bug,这时候工…

ChatGPT 修得了别人的 Bug,修不了自己的!OpenAI 直指开源数据库 Redis 漏了底

作者 | 屠敏 出品 | CSDN(ID:CSDNnews) ChatGPT 的火爆,超出了很多人的想象。今年初,根据 UBS(瑞士银行巨头瑞银集团)的一份报告显示,ChatGPT 推出仅两个月后,它在 2023 …

chatgpt赋能python:Python题库搜题:提高编程效率的利器

Python题库搜题:提高编程效率的利器 作为一名有10年Python编程经验的工程师,经常遇到需要快速查找解决问题的情况,而Python题库搜题是我常用的工具之一。本文将着重介绍Python题库搜题的功能和使用方法,以及如何通过优化搜索关键…

chatgpt赋能python:使用Python在SEO中找到完美数

使用Python在SEO中找到完美数 SEO是一项关键技能,它可以使网站或者博客在搜索引擎中获得更好的排名,吸引更多的访问者。Python是一门最流行的编程语言之一,它也是一个很好的SEO工具。本文将介绍如何使用Python来找到完美数,以帮助…

chatgpt赋能Python-python_jam

Python Jam:一个优秀的社区驱动Python学习平台 如果你正在寻找一个能够让你更进一步学习Python的平台,那么你可以考虑加入Python Jam社区。这是一个社区驱动的学习平台,旨在帮助Python学习者找到合适的资源和学习机会。 什么是Python Jam …

chatgpt赋能python:Python题目搜索软件:提升你的编程水平

Python题目搜索软件:提升你的编程水平 对于那些喜欢编程的人来说,学习Python是一个非常不错的选择。但是,学习Python的难度并不小,需要大量的时间和精力。一个好的学习方式是通过完成Python编程题目来加深对该编程语言的理解。但…

chatgpt赋能python:Python的题目该如何搜到答案?

Python 的题目该如何搜到答案? 如果你在学习 Python 的过程中遇到了问题,或者在工作中需要使用 Python 解决一些难题,那么你可能需要在网上搜索一些相关的题目和答案。但是,在众多的搜索结果中,究竟该如何找到最适合你…

当我跟ChatGPT说要写一本关于Python的教程书时。。。。

闲来无事,想让ChatGPT帮我列一份Python教程书的大纲。后续将尝试让ChatGPT根据这份大纲进行撰写。

chatgpt赋能python:Python描点画图详解:从基础到实战

Python描点画图详解:从基础到实战 Python是一种功能强大且易于学习的编程语言,它被广泛应用于机器学习、数据分析和可视化等领域。在数据可视化方面,Python有许多优秀的库和工具,其中最受欢迎的就是Matplotlib。我们将重点介绍如…

总结:一文搞懂chatGPT原理

目前关于chatGPT的资料过于零散,没有详尽所有知识点、系统概述的文章,因此,笔者作了这篇总结性文章。 训练过程总览 理清演化路径 预训练(pretrain) GPT-3概述 GPT 3模型的理念 GPT-3如何学习 数据集 指令微调 (Instruction Fine-Tunin…

【一文系列】一篇文章记录gpt API的使用过程(python版)

【一文系列】一篇文章记录gpt API的使用过程(python版) “一文系列”目标是仅通过一篇文章来解决一个类别问题,简洁高效,快速获取知识,提升技能。 文章目录 【一文系列】一篇文章记录gpt API的使用过程(pyt…

一个时代彻底结束了。

最近和几个大佬们吃饭,都感慨时间真的好快!85年的,如今都快40岁了。90后,也都快35了。有几个大佬经历了PC互联网时代,移动互联网时代。吃足了红利。如果是2010年开启的是移动互联网时代,那么从18年之后&…

原美团联合创始人欲打造中国版 OpenAI ;ChatGPT 爆红惊动谷歌退隐创始人布林;Gradle 8.0 发布|极客头条...

「极客头条」—— 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews) 一分钟速览新闻点&#…

一个时代彻底结束了!

点击上方“码农突围”,马上关注 这里是码农充电第一站,回复“666”,获取一份专属大礼包 真爱,请设置“星标”或点个“在看 这是【码农突围】的第 439 篇原创分享 作者 l 突围的鱼 来源 l 码农突围(ID:smart…

输出链表(c语言)

输出链表 描述格式样例题解及详细注释 描述 根据给定的数据建立一个由n(n≤1000)个元素组成的链表,然后按逻辑顺序输出其中所有的数据。 每个元素节点由两个域组成:第一个域存储数据,第二个域存储后继元素所在的位置…