2024.1.18 网络编程 作业

思维导图

练习题

1>TCP传输使用IO多路复用select完成客户端

#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.125.15"
#define CLI_PORT 9999
#define CLI_IP "192.168.125.15"
int main(int argc, char const *argv[])
{//创建用于连接的套接字int cfd = socket(AF_INET, SOCK_STREAM, 0);if (cfd == -1){perror("socket error");return -1;}//给套接字绑定端口IPstruct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(CLI_PORT);cin.sin_addr.s_addr = inet_addr(CLI_IP);//绑定,可选if (bind(cfd, (struct sockaddr *)&cin, sizeof(cin)) == -1){perror("bind error");return -1;}puts("bind success");//连接服务器//填充服务器地址结构体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 (connect(cfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){perror("bind sin error");return -1;}puts("connect success");//阻塞客户端int ret;fd_set fd;FD_ZERO(&fd);FD_SET(0, &fd);FD_SET(cfd, &fd);ret = select(cfd + 1, &fd, NULL, NULL, NULL);char buf[128] = "", buf1[128] = "";//客户端收发操作while (1){memset(buf, 0, sizeof(buf));memset(buf1, 0, sizeof(buf1));//接收服务器消息事件触发if (FD_ISSET(cfd, &fd)){if (recv(cfd, buf1, sizeof(buf1), 0) < 0){perror("recv error");return -1;}printf("%s\n", buf1);continue;}//发送事件触发if (FD_ISSET(0, &fd)){fgets(buf, sizeof(buf), stdin);buf[strlen(buf) - 1] = '\0';if (strcmp(buf, "quit") == 0)break;if (send(cfd, buf, strlen(buf), 0) < 0){perror("send error");return -1;}continue;}}
END://关闭套接字close(cfd);return 0;
}

2>TCP传输实现IO多路复用poll的服务器端

#include <myhead.h>
#define PORT 8888
#define IP "192.168.125.15"
#define OPEN_MAX 10
int main(int argc, char const *argv[])
{//创建tcp监听套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);//2.绑定sockfdstruct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);if (bind(sockfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){perror("bind error");return -1;}puts("bind success");//监听listenif (listen(sockfd, 128) == -1){perror("listen error");return -1;}puts("listen success");//poll相应参数准备struct pollfd pfd[OPEN_MAX];int i = 1, maxi = 1;//初始化poll结构中的文件描述符fdfor (; i < OPEN_MAX; i++)pfd[i].fd = -1;pfd[0].fd = 0;pfd[0].events = POLLIN;pfd[1].fd = sockfd;pfd[1].events = POLLIN;//对已连接的客户端的数据处理while (1){//阻塞检测集合中是否有事件产生,-1表示一直阻塞int ret = poll(pfd, maxi + 1, -1);struct sockaddr_in cin;socklen_t socklen = sizeof(cin);//检测0号描述符if (pfd[0].revents == POLLIN){//终端输入char buf[128] = "";scanf("%s", buf);if (strcmp(buf, "quit") == 0){break;}}//监测sockfd是否存在连接if (pfd[1].revents == POLLIN){int res = 0;//获取客户端res = accept(sockfd, (struct sockaddr *)&cin, &socklen);printf("[%s:%d]发来连接请求\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));//将提取到的res放入poll结构体数组中,以便于监测for (i = 2; i < OPEN_MAX; i++){if (pfd[i].fd < 0){pfd[i].fd = res;pfd[i].events = POLLIN;break;}}//maxi更新if (i > maxi)maxi = i;//如果没有就绪的描述符,就继续poll监测,否则继续向下看if (--res <= 0)continue;}//继续响应就绪的描述符for (i = 2; i <= maxi; i++){if (pfd[i].revents == POLLIN){int len = 0;char buf[128] = "";//接受客户端数据if ((len = recv(pfd[i].fd, buf, sizeof(buf), 0)) < 0){perror("recv error");return -1;}else if (len == 0) //客户端关闭连接{puts("客户端下线");close(pfd[i].fd);pfd[i].fd = -1;}else{printf("[%s:%d]%s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);//正常接收到服务器的数据strcat(buf, "^.^");send(pfd[i].fd, buf, sizeof(buf), 0);}//所有的就绪描述符处理完了,就退出当前的for循环,继续poll监测if (--ret <= 0)break;}}}close(sockfd);return 0;
}

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

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

相关文章

深入解析JavaScript的原生原型

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 在JavaScript中,除了自定义对象,还存在很多由JavaScript语言本身提供…

Docker之nacos的安装和使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《Docker之Dockerfile构建镜像》。&#x1f3af;&…

肯尼斯·里科《C和指针》第6章 指针(1)

作为补充资料来学习吧。 6.1 内存和地址 前面提到&#xff0c;我们可以把计算机的内存看作一条长街上的一排房屋。每座房子都可以容纳数据&#xff0c;并通过一个房号来标识。这个比喻颇为有用&#xff0c;但也存在局限性。计算机的内存由数以亿万计的位(bit)组成&#xff0c;…

[Android] Android架构体系(2)

文章目录 Bionic精简对系统调用的支持:不支持 System V IPC:有限的 Pthread 功能:有限支持C:不再支持本地化和/或宽字符:Bionic新增的特性系统属性硬编码写死的UID/GID内置了DNS解析硬编码写死的服务和协议 硬件抽象层Linux内核匿名共享内存(ASHMem)Binder-BinderLoggerION 内存…

【经典算法】有趣的算法之---粒子群算法梳理

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 粒子群算法 粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;PSO&#xff09;是一种用于解决优化问题的元启发式算法。它通过模拟鸟群或…

什么是车载信息娱乐系统和集成驾驶舱

什么是车载信息娱乐系统(IVI)? “车载信息娱乐(IVI)”通过向驾驶员和乘客提供信息和娱乐&#xff0c;为驾驶提供便利和舒适。为了理解这个概念&#xff0c;有必要知道“信息娱乐”的含义。“信息娱乐”是这个市场中使用的一个词&#xff0c;它结合了“信息”和“娱乐”两个词…

编译FFmpeg4.3.1 、x264并移植到Android

1、前言 FFmpeg 既是一款音视频编解码工具&#xff0c;同时也是一组音视频编解码开发套件。 2、准备工作 系统&#xff1a;LinuxNDK&#xff1a;android-ndk-r21b-linux-x86_64.zipFFmpeg&#xff1a;ffmpeg-snapshot.tar.bz2x264&#xff1a;x264 3、下载NDK 在linux环境中…

存内计算技术打破常规算力局限性

说明&#xff1a; 本文撰写人&#xff1a;三掌柜666 由三掌柜666原创首发&#xff1a;https://blog.csdn.net/CC1991_/article/details/135623056 文章目录 前言关于存内计算1、常规算力局限性2、存内计算诞生记3、存内计算核心 存内计算芯片研发历程及商业化1、存内计算芯片研…

Unix时间戳

时间戳&#xff0c;相信很多相关专业的人&#xff0c;计算机软件电子等等都会听过。由于最早是由Unix系统使用所以又叫Unix时间戳。 Unix 时间戳&#xff08;Unix Timestamp&#xff09;定义为从UTC&#xff08;世界协调时&#xff09;/GMT&#xff08;格林尼治时&#xff09;…

【Java】SpringBoot快速整合Redis

什么是Redis&#xff1f; 文末有源码gitee地址 【面试】浅学Redis_redis 广播-CSDN博客 Redis是一种高性能开源的基于内存的&#xff0c;采用键值对存储的非关系型数据库&#xff0c;它支持多种数据结构&#xff0c;包括字符串、哈希表、列表、集合、有序集合等。Redis的特点之…

机器学习--Matplotlib

机器学习–Matplotlib Matplotlib 是专门用于开发2D图表(包括3D图表)以渐进、交互式方式实现数据可视化 简单的Matplotlib画图 — 以折线图为例 matplotlib.pyplot模块 matplotlib.pytplot包含了一系列类似于matlab的画图函数。 import matplotlib.pyplot as plt图形绘制流…

STM32入门教程-2023版【4-1】OLED调试工具

关注 点赞 不错过精彩内容 大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 一、概述 在这一节先提前介绍一下&#xff0c;在以后的教程中我们会经常用到这个显示屏&#xff0…