网络编程 day6

网络聊天室项目

1.服务器端

#include <head.h>
#define SER_IP "192.168.125.11"
#define SER_PORT 6666
typedef struct Msg
{char user[32];   //用户名int type;        //1.登录、2.发消息、0.退出char text[1024]; //消息
} msg_t;
typedef struct List
{struct sockaddr_in cin; //客户端网络信息结构体struct List *next;      //链表指针
} * list;struct sockaddr_in cin;
//创建头节点
list list_create()
{list p = (list)malloc(sizeof(struct List));if (p == NULL){perror("create list error");}p->next = NULL;p = NULL;
}//向所有客户端发送消息
void *task(void *arg)
{int *sockfd = (int *)arg;msg_t msg;strcpy(msg.user, "*system*");while (1){scanf("%s", msg.text);getchar();if (strncmp(msg.text, "quit", 4) == 0){exit(0);}sendto(*sockfd, msg.text, sizeof(msg), 0, (struct sockaddr *)&cin, sizeof(cin));}
}
//登录
void login(int sockfd, msg_t msg, list p, struct sockaddr_in cin)
{list newusr = NULL;new = (list)malloc(sizeof(struct List));sprintf(msg.text, "login");while (p->next != NULL){//发送给其他客户端登录消息p = p->next;sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&(p->cin), sizeof(p->cin));printf("[%s:%d]:%s login\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), msg.user);}//新节点的数据域填充新客户地址结构体newusr->cin = cin;p->next = new;new->next = NULL;
}
//接收客户端消息事件处理
void chatmsg(int sockfd, msg_t msg, list p, struct sockaddr_in cin)
{//将客户端发来的消息发送给其他客户端while (p->next != NULL){p = p->next;sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&(p->cin), sizeof(p->cin));}
}//客户端退出
void quit(int sockfd, msg_t msg, list p, struct sockaddr_in cin)
{list del = NULL;sprintf(msg.text, "%s out", msg.user);while (p->next != NULL){//遍历链表找要退出的客户端地址结构体的前一个if (memcmp(&(p->next->cin), &cin, sizeof(cin)) == 0){del = p->next;p->next = del->next;free(del);del = NULL;}else{p = p->next;sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&(p->cin), sizeof(p->cin));}}
}
int main(int argc, char const *argv[])
{msg_t msg;//创建套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd == -1){perror("socket error");return -1;}struct sockaddr_in sin;//填充服务器地址结构体sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);sin.sin_addr.s_addr = inet_addr(SER_IP);//绑定服务器if (bind(sockfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){perror("bind error");return -1;}//创建客户端地址结构体struct sockaddr_in cin;//获取客户端地址结构体大小socklen_t socklen = sizeof(cin);//创建链表节点list p = list_create();//创建线程pthread_t tid;if (pthread_create(&tid, NULL, task, &sockfd) == -1){printf("pthread_create error\n");return -1;}//分离线程pthread_detach(tid);//接收客户端消息while (1){//接收客户端发来的消息,返回消息字符个数int res = recvfrom(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&cin, &socklen);if (res < 0){perror("recvfrom error");return -1;}//判断客户端状态 登录(1) 消息(2) 退出(0)if (msg.type == 1){login(sockfd, msg, p, cin);}else if (msg.type == 2){chatmsg(sockfd, msg, p, cin);}else if (msg.type == 0){printf("[%s:%d] %s out\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), msg.user);quit(sockfd, msg, p, cin);}}//关闭套接字close(sockfd);return 0;
}

 2.客户端

#include <head.h>
#define SER_IP "192.168.125.11"
#define SER_PORT 6666typedef struct Msg
{char user[32];   //用户名int type;        //1登录、2发消息、0退出char text[1024]; //消息
} msg_t;int main(int argc, char const *argv[])
{int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd == -1){perror("sock error");return -1;}msg_t msg;struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_addr.s_addr = inet_addr(SER_IP);cin.sin_port = htons(SER_PORT);socklen_t socklen = sizeof(cin);char buf[128] = "";msg.type = 1;printf("please imput your name:");scanf("%s", msg.user);getchar();sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&cin, socklen);pid_t pid = fork();if (pid < 0){perror("fork error");return -1;}//子进程循环else if (pid == 0){while (1){printf("---------------------\n");scanf("%s", msg.text);getchar();if (strncmp(msg.text, "quit", 4) == 0){msg.type = 0;sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&cin, socklen);kill(pid, SIGINT);exit(0);wait(NULL);}else{msg.type = 2;}sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr *)&cin, socklen);}}//父进程循环接收消息else {int res;while (1){res = recv(sockfd, &msg, sizeof(msg), 0);if (res == -1){perror("recv error");return -1;}printf("[%s]:%s\n", msg.user, msg.text);}wait(NULL);}close(sockfd);return 0;
}

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

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

相关文章

高德地图官方首度揭秘:红绿灯倒计时功能是如何实现的?

今年元旦&#xff0c;小编喜提新车后&#xff0c;第一次使用高德地图 App 驾车模式&#xff0c;在路口等红灯时立刻被红绿灯倒计时读秒功能惊艳了&#xff0c;竟能够准确地显示红绿灯的剩余时间&#xff01;好奇心驱使我&#xff0c;不禁想弄明白怎么神奇的功能是如何实现的呢&…

SSL通配符免费申请

通配符SSL证书是一种可以用于保护主域名及其所有子域名的证书。通配符SSL证书使用通配符&#xff08;*&#xff09;来代表所有子域名&#xff0c;使得只需一个证书就可以覆盖多个子域名。 要申请通配符SSL证书&#xff0c;您可以按照以下步骤进行&#xff1a; 选择SSL证书提供…

结构体的内存对齐(计算题常考点)

许久不见我考完试回来啦&#xff0c;让我们接着将结构体进行到底&#xff01; 目录 结构体对齐的意义&#xff1a; 结构体对齐的实现&#xff1a; 对齐规则&#xff1a; 训练&#xff1a; 好到这里误区来了&#xff1a; 总结&#xff1a; 往期回顾&#xff1a; 下期预告&…

机器学习周记(第二十六周:文献阅读-DPGCN)2024.1.15~2024.1.21

目录 摘要 ABSTRACT 1 论文信息 1.1 论文标题 1.2 论文摘要 1.3 论文背景 2 论文模型 2.1 问题描述 2.2 论文模型 2.2.1 时间感知离散图结构估计&#xff08;Time-aware Discrete Graph Structure Estimation Module&#xff0c;TADG Module&#xff09; 2.2.2 时间…

html 会跳舞的时间动画特效

下面是是代码&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta h…

LeetCode 77. 组合

77. 组合 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ] 示例 2&#xff1a; 输入&#xff1a;…

说说你对归并排序的理解?如何实现?应用场景?

一、是什么 归并排序&#xff08;Merge Sort&#xff09;是建立归并操作上的一种有效&#xff0c;稳定的排序算法&#xff0c;该算法是采用分治法的一个非常典型的应用 将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;即先使每个子序列有序&#xff0c;再使…

nodejs下载安装

一、node下载安装 官网下载 官网 根据自己电脑系统选择合适的版本进行下载&#xff0c;我这里选择window 64 位 下载完点击安装 打开cmd查看安装 此处说明下&#xff1a;新版的Node.js已自带npm&#xff0c;安装Node.js时会一起安装&#xff0c;npm的作用就是对Node.js…

Go使用记忆化搜索的套路【以20240121力扣每日一题为例】

题目 分析 这道题很明显记忆化搜索&#xff0c;用py很容易写出来 Python class Solution:def splitArray(self, nums: List[int], k: int) -> int:n len(nums)# 寻找分割子数组中和的最小的最大值s [0]for num in nums:s.append(s[-1] num)#print(s)cachedef dfs(cur,…

Spring boot项目java bean和xml互转

Spring boot项目实现java bean和xml互转 项目场景&#xff1a;互转方法使用jackson进行互转使用jaxws进行xml与bean的互转 搞定收工&#xff01; 项目场景&#xff1a; 工作中需要给下游第三方收费系统做数据挡板&#xff0c;由于下游系统使用的是soap webservice,里面涉及各种…

第91讲:MySQL主从复制集群主库与从库状态信息的含义

文章目录 1.主从复制集群正常状态信息2.从库状态信息中重要参数的含义 1.主从复制集群正常状态信息 通过以下命令查看主库的状态信息。 mysql> show processlist;在主库中查询当前数据库中的进程&#xff0c;看到Master has sent all binlog to slave; waiting for more u…

《WebKit 技术内幕》之六(3): CSS解释器和样式布局

3 WebKit布局 3.1 基础 当WebKit创建RenderObject对象之后&#xff0c;每个对象是不知道自己的位置、大小等信息的&#xff0c;WebKit根据框模型来计算它们的位置、大小等信息的过程称为布局计算&#xff08;或者称为排版&#xff09;。 图描述了这一过程中涉及的主要WebKit…

【解决方法】PPT不能编辑,按钮都是灰色,怎么办?

PPT文件打开之后&#xff0c;发现无法编辑&#xff0c;再仔细查看发现工具栏中的功能按钮都是灰色的&#xff0c;无法使用&#xff0c;这是什么原因&#xff1f;该如何解决&#xff1f; 原因&#xff1a;无法编辑PPT文件&#xff0c;并且功能按钮都是灰色&#xff0c;这是因为…

qnx 上screen + egl + opengles 最简实例

文章目录 前言一、qnx 上的窗口系统——screen二、screen + egl + opengles 最简实例1.使用 addvariant 命令创建工程目录2. 添加源码文件3. common.mk 文件4. 编译与执行总结参考资料前言 本文主要介绍如何在QNX 系统上使用egl和opengles 控制GPU渲染一个三角形并显示到屏幕上…

cuda中的定点数优化技术

这里学习一下定点数的优化操作&#xff0c;实际上就是以整数代替浮点数&#xff0c;乘除法的操作均通过左右移位来实现&#xff0c;适合在算力非常低的场景下使用&#xff0c;极致的压榨性能。 https://zhuanlan.zhihu.com/p/338588296 定点数介绍 以下给出函数的具体实现&…

纸黄金实战投资技巧:避免亏损的有效策略

在纸黄金交易的实战中&#xff0c;避免亏损是每位投资者都追求的目标。虽然任何投资都存在一定的风险&#xff0c;但采取一些有效的策略可以帮助投资者最大限度地减少亏损的可能性。以下是一些在纸黄金交易中避免亏损的实战技巧&#xff1a; 一、设定止损点是避免亏损的关键 止…

【Linux】

Linux零基础入门 列出文件/文件夹新建/切换路径查看当前路径重命名或者移动文件夹拷贝文件/文件夹删除文件夹设置环境变量编辑文本文件压缩和解压查看cpu的信息查看/杀死进程查看进程的CPU和内存占用重定向日志场景一场景二场景三场景四 列出文件/文件夹 命令&#xff1a;Ls(L…

All the stories begin at installation

Before installation, there are some key points about Conan: “Conan is a dependency and package manager for C and C languages.”“With full binary management, Conan can create and reuse any number of different binaries (for different configurations like a…

基于SpringBoot的智慧社区居家养老健康管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

Kafka常见指令及监控程序介绍

kafka在流数据、IO削峰上非常有用&#xff0c;以下对于这款程序&#xff0c;做一些常见指令介绍。 下文使用–bootstrap-server 10.0.0.102:9092,10.0.0.103:9092,10.0.0.104:9092 需自行填写各自对应的集群IP和kafka的端口。 该写法 等同 –bootstrap-server localhost:9092 …