day7-网络编程

1>基于UDP的网络聊天室

Ser.c

#include <myhead.h>
#define SER_IP "10.211.55.9" // 服务器IP
#define SER_PORT 9999struct user
{char usrName[20];struct sockaddr_in cin;
};
int main(int argc, char const *argv[])
{// 1.创建用于监听的套接字int sfd = -1;sfd = socket(AF_INET, SOCK_STREAM, 0);// 参数1:表示使用的是ipv4的通信// 参数2:表示使用tcp通信类型// 参数3:表示前面已经特定了通信协议if (sfd == -1)PRINT_ERR("");printf("sfd = %d\n", sfd);int reuse = 1;if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)PRINT_ERR("");// 2、绑定ip地址和端口号// 2.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); // IP地址// 2.2绑定if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){perror("bind error");return -1;}printf("bind success\n");// 3、启动监听,允许客户端连接if (listen(sfd, 128) == -1){perror("listen error");return -1;}printf("listen success\n");struct sockaddr_in cin;          // 用于接收客户端地址信息结构体socklen_t socklen = sizeof(cin); // 用于接收客户端地址信息的大小int newfd = -1;                  // 新创建用于通信的套接字文件描述符char sbuf[128] = "";             // 从键盘上输入数据// 1.创建文件描述符容器fd_set readfds, tempfds;// 2.清空容器内容FD_ZERO(&readfds);// 3.将sfd和0号文件描述符放入容器中FD_SET(0, &readfds);FD_SET(sfd, &readfds);int maxfd = sfd; //  存放容器中最大的文件描述符的值struct user User[1024];while (1){tempfds = readfds; //  将要检测的容器复制保存一份int res = select(maxfd + 1, &tempfds, NULL, NULL, NULL);if (res == -1)PRINT_ERR("select error");else if (res == 0){printf("time out\n");return -1;}// 遍历所有的容器中的文件描述符for (int i = 0; i <= maxfd; i++){// 判断当前的文件描述符是否在tempfds中,如果不在,直接下一个循环if (!FD_ISSET(i, &tempfds))continue;// 如果程序执行到此,说明检测的集合中有事件产生if (i == sfd){newfd = accept(i, (struct sockaddr *)&cin, &socklen);if (newfd == -1)PRINT_ERR("");recv(newfd, User[newfd].usrName, sizeof(User[newfd].usrName), 0);printf("%s [%s:%d]登陆成功\n", User[newfd].usrName, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));// 将客户端文件描述符放入集合中FD_SET(newfd, &readfds);// 更新maxfdif (newfd > maxfd){maxfd = newfd;}// 打包信息bzero(sbuf, sizeof(sbuf));sprintf(sbuf,"-----%s登陆成功-----",User[newfd].usrName);//    strcat(sbuf, "-----");//    strcat(sbuf, User[newfd].usrName);//    strcat(sbuf, "登陆成功-----");// 将消息发给每一个客户端for (int k = 4; k <= maxfd; k++){if (k == i)continue;send(k, sbuf, strlen(sbuf), 0);}}else if (i == 0) // 表示有终端输入事件{// 将消息发送给每一个客户端bzero(sbuf, sizeof(sbuf));fgets(sbuf, sizeof(sbuf), stdin);sbuf[strlen(sbuf) - 1] = 0;char sbuf1[128] = "Sys:";strcat(sbuf1, sbuf);// 将消息发给每一个客户端for (int k = 4; k <= maxfd; k++){send(k, sbuf1, strlen(sbuf1), 0);}}else{// 5、通信套接字与客户端进行数据收发char rbuf[128] = ""; // 数据读取// 清空容器bzero(rbuf, sizeof(rbuf));// 从套接字中读取数据int res = recv(i, rbuf, sizeof(rbuf), 0);if (res == 0){//    strcat(rbuf, "-----");//    strcat(rbuf, User[i].usrName);//    strcat(rbuf, " 已下线-----");sprintf(rbuf,"-----%s已下线-----",User[i].usrName);// 将消息发给每一个客户端for (int k = 4; k <= maxfd; k++){if (k == i)continue;send(k, rbuf, strlen(rbuf), 0);}bzero(User[i].usrName, sizeof(User[i].usrName));// 6、关闭套接字close(i);// 将当前文件描述符从容器中移除FD_CLR(i, &readfds);// 更新maxfdfor (int j = maxfd; j >= 0; j--){if (FD_ISSET(j, &readfds)){maxfd = j;break;}}}else if (strcmp(rbuf, "quit") != 0){printf("%s [%s:%d]chart成功\n", User[i].usrName, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));char wbuf[128] = "";strcat(wbuf, User[i].usrName);strcat(wbuf, ":");strcat(wbuf, rbuf);// 将消息发给每一个客户端for (int k = 4; k <= maxfd; k++){if (k == i)continue;send(k, wbuf, strlen(wbuf), 0);}}bzero(rbuf, sizeof(rbuf));}}}close(sfd);return 0;
}

Cli.c

#include <myhead.h>
#define SER_IP "10.211.55.9" // 服务器IP
#define SER_PORT 9999struct msgTyp
{char usrName[20];char msgText[1024];
};int main(int argc, const char *argv[])
{struct msgTyp User = {0, 0};printf("请输入姓名>>>");scanf("%s", User.usrName);// 1、创建用于通信的套接字文件描述符int cfd = socket(AF_INET, SOCK_STREAM, 0);if (cfd == -1){perror("socket error");return -1;}printf("cfd = %d\n", cfd); // 3// 2、绑定(非必须)// 3、连接服务器// 3.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); // ip地址// 3.2 连接服务器if (connect(cfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){perror("connect error");return -1;}printf("connect success\n");//向服务器发送上线信息send(cfd, User.usrName, strlen(User.usrName), 0);// 使用poll完成客户端的读写操作并发执行// 1、定义一个pollfd数组struct pollfd pfd[2];pfd[0].fd = 0;          // 检测0号文件描述符pfd[0].events = POLLIN; // 检测0号文件描述符的读操作pfd[1].fd = cfd;        // 检测cfd文件描述符pfd[1].events = POLLIN; // 检测cfd中的读操作// 4、数据收发while (1){int res = poll(pfd, 2, -1); // 阻塞检测集合中是否有事件产生if (res == -1){perror("poll error");return -1;}else if (poll == 0){printf("time out\n");return -1;}// 程序执行至此,表示有事件产生if (pfd[0].revents == POLLIN) // 表示0号文件描述符事件产生{// 清空数据bzero(&User.msgText, sizeof(User.msgText));fgets(User.msgText, sizeof(User.msgText), stdin); // 从终端输入User.msgText[strlen(User.msgText) - 1] = 0;// 将数据发送给服务器send(cfd, User.msgText, strlen(User.msgText), 0);// 判断发送的数据if (strcmp(User.msgText, "quit") == 0){break;}}if (pfd[1].revents == POLLIN) // 表示cfd文件描述符事件产生{// 接收服务器发来的消息// 清空数据bzero(User.msgText, sizeof(User.msgText));recv(cfd, User.msgText, sizeof(User.msgText), 0);printf("%s\n", User.msgText);}}// 5、关闭套接字close(cfd);return 0;
}

结果:

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

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

相关文章

MyBatis-Flex学习总结

写在前面的话 MyBatis-Flex 是一个优雅的 MyBatis 增强框架&#xff0c;它非常轻量、同时拥有极高的性能与灵活性。我们可以轻松的使用 Mybaits-Flex 链接任何数据库&#xff0c;其内置的 QueryWrapper 帮助我们极大的减少了 SQL 编写的工作的同时&#xff0c;减少出错的可能性…

Urban Elevations(UBA-211)

网址如下&#xff1a; Urban Elevations - UVA 221 - Virtual Judge (vjudge.net) 第三方网站的 说实话&#xff0c;我看英语看得头大 最近学了一堆stl的容器&#xff0c;比如map&#xff0c;set啥的&#xff0c;方便是很方便&#xff0c;但是导致我脑子里第一个念头就是用他…

鸿蒙开发岗成春招最大黑马,“金三银四”应届生如何突围?

一年一度春招时间到&#xff0c;技术岗位已成为众多人才竞相追求的“职业高地”&#xff0c;也是未来职业发展的重要方向之一。鸿蒙人才在春招市场上成为“香饽饽”&#xff0c;与往年不同的是&#xff0c;许多应届生放弃考公执念向程序员进攻&#xff0c;这一现象背后蕴含着深…

腾讯云服务器和阿里云服务器价格测评_2024年费用大PK

2024年阿里云服务器和腾讯云服务器价格战已经打响&#xff0c;阿里云服务器优惠61元一年起&#xff0c;腾讯云服务器61元一年&#xff0c;2核2G3M、2核4G、4核8G、4核16G、8核16G、16核32G、16核64G等配置价格对比&#xff0c;阿腾云atengyun.com整理阿里云和腾讯云服务器详细配…

day52(vueJS)json-server模拟数据

json-server介绍&#xff1a;&#xff1a;&#xff1a;JSON Server 是一个用于快速搭建 REST API 的工具&#xff0c;它可以帮助我们在开发过程中快速模拟 一个后端 API 服务器&#xff0c;方便前端开发人员进行接口调试和开发。使用 JSON Server&#xff0c;你可以通过创建一个…

【Go】golang值交换,指针

package mainimport "fmt"func swap(a *int, b *int) int {var o into *a*a *b*b oreturn o}func main() {var a int 1var b int 2swap(&a, &b)fmt.Println(a, b) }这个函数接受两个整数指针作为参数&#xff0c;然后通过指针操作&#xff0c;交换它们所…

第三百八十七回

文章目录 1. 概念介绍2. 使用方法3. 示例代码 我们在上一章回中介绍了DateRangePickerDialog Widget相关的内容,本章回中将介绍Radio Widget.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在这里说的Radio Widget是指单选按钮&#xff0c;没有选中时是圆形…

python 实现文件系统监控:实现文件增加、删除、修改的监听

在Python中&#xff0c;你可以使用watchdog库来实现文件系统监控功能。下面是一个基础的看门狗&#xff08;Watchdog&#xff09;示例&#xff0c;它会监视指定目录下的文件和子目录的变化&#xff0c;并对特定事件&#xff08;如文件创建、修改或删除&#xff09;做出响应&…

代码随想录算法训练营第二天|977、有序数组的平方

977. 有序数组的平方 已解答 简单 相关标签 相关企业 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,…

Linux设备模型(七) - Netlink

一&#xff0c;什么是netlink通信机制 Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。Netlink 是一种特殊的 socket&#xff0c;它是 Linux 所特有的。 Netlink 是一种在内核与用户应用间进行双向数…

我的创作周年纪念日

机缘 最初成为创作者的初心&#xff1a;整理自己的知识体系&#xff0c;普及前端知识 实战项目中的经验分享日常工作学习过程中的记录通过文章进行技术交流归纳和整理自己的知识体系 收获 创作的过程中收获&#xff1a; 获得了909粉丝的关注获得了很多正向的反馈&#xff0c…

【C语言】终の指针(前篇)

个人主页点这里~ 指针初阶点这里~ 指针初阶2.0点这里~ 指针进阶点这里~ 终の指针 一、回调函数二、qsort函数1、整形比较2、结构数据比较①结构体②-> 的使用③结构数据比较 一、回调函数 回调函数就是⼀个通过函数指针调用的函数。 把一个函数的指针作为参数传递给另一…

.NET 8.0:塑造未来的技术革新

随着科技的不断发展&#xff0c;.NET 框架作为微软推出的开源、跨平台开发框架&#xff0c;已经成为全球数百万开发者的首选工具。作为.NET 框架的最新版本&#xff0c;.NET 8.0 带来了许多令人振奋的新特性和改进&#xff0c;旨在帮助开发者构建更高效、更可靠的应用程序。本文…

dubbo3适配springboot2.7.3

版本详细 <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId><version>3.0.3</version> </dependency><parent><groupId>org.springframework.boot</groupId><artifactId&…

leetcode热题100刷题计划

题目3 无重复字符的最长子串 思路 滑动窗口&#xff0c;设定当前窗口左侧为i&#xff0c;右侧为right&#xff0c;当到达右侧边界时&#xff0c;记录长度&#xff0c; 然后删掉最左侧的字符&#xff0c;即i1&#xff1b;right则继续向后搜。 代码 public int lengthOfLong…

面试题之——Cookie和Session的区别

面试题之——Cookie和Session的区别 一.存储位置 Cookie存储在客户端&#xff08;浏览器&#xff09;当中Session存储在服务器当中 二.安全性 Cookie由于存储在客户端当中&#xff0c;Cookie数据可以被用户或其他恶意程序直接访问和修改&#xff0c;因此存在被窃取或篡改的…

mysql数据库入门到精通-Windows版本mysql安装(1)

文章目录 一、数据库介绍1.1、数据库概念1.2、为什么要使用数据库1.3、关系型数据库与非关系型数据库1.4、数据库术语1.5、mysql下载及地址 二、安装mysql数据库三、mysql的管理工具3.1、mysql command line client使用 四、SQL结构化查询语言4.1、SQL概述4.2、SQL发展4.3、SQL…

水牛社:专为创业者和网赚小白精心打造的助手

近几年来&#xff0c;经济发展快是快&#xff0c;物价也在蹭蹭往上涨&#xff0c;但工资却不见明显提升&#xff0c;随着生活成本的增加&#xff0c;单单靠工资&#xff0c;已经很难维持生活开支&#xff0c;加之疫情的影响&#xff0c;很多行业发展不景气&#xff0c;一些岗位…

医学大数据|统计基础|医学统计学(笔记):开学说明与目录

开始学习统计基础&#xff0c;参考教材&#xff1a;医学统计学第五版 点点关注一切来学习吧 责任编辑&#xff1a;医学大数据刘刘老师&#xff1a;头部医疗大数据公司医学科学部研究员 邮箱&#xff1a;897282268qq.com 久菜盒子工作室 我们是&#xff1a;985硕博/美国全奖…

python 输入和输出

在 Python 中&#xff0c;输入和输出是最基本的操作之一。你可以使用内置函数 input() 来获取用户输入&#xff0c;使用 print() 函数来输出信息到控制台。 输入&#xff08;Input&#xff09; input() 函数用于从用户那里获取输入。这个函数会将用户的输入作为字符串返回。 示…