2024.3.5 网络编程

news2024/11/18 5:56:37

思维导图

复习课堂作业:IO多路复用

select 实现服务端

#include<myhead.h>
#define SER_IP "192.168.68.154"
#define SER_PORT 1234
 
int main(int argc, const char *argv[])
{
	//1、创建用于监听的套接字
	int sfd = -1;
	sfd=socket(AF_INET, SOCK_STREAM, 0);
	//参数1:表示使用的是ipv4的通信
	//参数2:表示使用tcp通信类型
	//参数3:表示前面已经特定了通信协议
	if(sfd == -1)
	{
		perror("socket error");
		return -1;
	}
 
	printf("sfd = %d\n", sfd);             //3
 
 
	//将端口号快速重用
	int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1)
	{
		perror("setsockopt error");
		return -1;
	}
	printf("端口号快速重用成功\n");
 
 
	//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");
 
	//4、当有客户端发来连接请求后创建新的用于通信的套接字
	//如果不想接收客户端地址信息结构体,则无需传入参数2和参数3
	//如果想要获取客户端地址信息结构体,则需要传入相关参数
 
	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 sockaddr_in cin_arr[1024];    //存放客户端对应的地址信息
 
 
	while(1)
	{
		tempfds = readfds;      //将要检测的容器复制保存一份
 
		int res = select(maxfd+1, &tempfds, NULL, NULL, NULL);  //阻塞等待集合中事件产生
		if(res == -1)
		{
			perror("select error");
			return -1;
		}else if(res == 0)
		{
			printf("time out\n");
			return -1;
		}
		//遍历所有的容器中的文件描述符
		for(int i=0; i<=maxfd; i++)
		{
			//判断当前的文件描述符是否在tempfds中,如果不在,直接下一个
			if(!FD_ISSET(i, &tempfds))
			{
				continue;
			}
 
			//如果程序执行到此,说明检测的集合中的i文件描述符产生了事件
 
			if(i == sfd)       //表示sfd触发了事件
			{
				newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);
				if(newfd == -1)
				{
					perror("accept error");
					return -1;
				}
 
				printf("newfd = %d 您有新的客户已经上线\n", newfd);
				printf("客户端IP:%s, 端口号为:%d\n", inet_ntoa(cin.sin_addr),  ntohs(cin.sin_port));
 
				//将客户端文件描述符放入到集合中
				FD_SET(newfd, &readfds);
				cin_arr[newfd] = cin;         //将新的客户端地址信息放入容器
				//更新一下maxfd
				if(newfd > maxfd)
				{
					maxfd = newfd;
				}
			}else if(i == 0)     //表示有终端输入事件
			{
				//从键盘输入数据
				fgets(sbuf, sizeof(sbuf), stdin);
				sbuf[strlen(sbuf)-1] = 0;
				printf("触发了键盘输入事件:%s\n", sbuf);
 
				//将消息发给每一个客户端
				for(int k=4; k<=maxfd; k++)
				{
					send(k, sbuf, strlen(sbuf), 0);
				}
 
 
			}else
			{
				//5、通信套接字与客户端进行数据收发
				char rbuf[128] = "";
 
				//清空容器
				bzero(rbuf, sizeof(rbuf));
 
				//从套接字中读取数据
				int res = recv(i, rbuf, sizeof(rbuf), 0);
				if(res == 0)
				{
					printf("客户端已经下线\n");
					//6、关闭套接字
					close(i);
 
					//将当前文件描述符从容器中移除
					FD_CLR(i, &readfds);
					//更新maxfd
					for(int j=maxfd; j>=0; j--)
					{
						if(FD_ISSET(j, &readfds))
						{
							maxfd = j;
							break;
						}
					}
 
 
					continue;
				}
 
				printf("[%s:%d] :%s\n", \
						inet_ntoa(cin_arr[i].sin_addr),  ntohs(cin_arr[i].sin_port), rbuf);
 
				//将收到的消息加上其他字符回过去
				strcat(rbuf, "*_*");
				send(i, rbuf, strlen(rbuf), 0);
 
			}
		}
	}
	close(sfd);
 
	return 0;
}

poll实现客户端

#include<myhead.h>
#define SER_IP "192.168.68.154"    //服务器IP
#define SER_PORT 1234
 
#define CLI_IP "192.168.68.154"   //客户端IP
#define CLI_PORT 1235             //客户端端口号
 
int main(int argc, const char *argv[])
{
	//1、创建用于通信的套接字文件描述符
	int cfd = socket(AF_INET, SOCK_STREAM, 0);
	if(cfd == -1)
	{
		perror("socket error");
		return -1;
	}
	printf("cfd = %d\n",cfd);
 
	//2、绑定(非必须)
	//2.1 填充地址信息结构体
	struct sockaddr_in cin;
	cin.sin_family = AF_INET;
	cin.sin_port = htons(CLI_PORT);
	cin.sin_addr.s_addr = inet_addr(CLI_IP);
	//2.2 绑定
	if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1)
	{
		perror("bind error");
		return -1;
	}
	printf("bind success!\n");
	//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");
	//使用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、数据收发
	char wbuf[128] = "";
	while(1)
	{
		int res = poll(pfd, 2, -1); //阻塞检测集合中是否有事件产生
		if(res == -1)
		{
			perror("poll error");
			return -1;
		}
		else if(res == 0)
		{
			printf("time out\n");
			return -1;
		}
		//文件执行至此,表示有事件产生
		if(pfd[0].events == POLLIN)   //表示0号描述符事件产生
		{
 
			//清空数据
			bzero(wbuf, sizeof(wbuf));
			printf("请输入>>>");
			fgets(wbuf, sizeof(wbuf), stdin);
			wbuf[strlen(wbuf)-1] = 0;
 
			//将数据发送给服务器
			send(cfd, wbuf, strlen(wbuf), 0);
			printf("发送成功!\n");
 
			//判断发送的数据
			if(strcmp(wbuf, "quit") == 0)
				break;
		}
		if(pfd[1].revents == POLLIN)    //表示cfd文件描述符事件产生
		{
			//接受服务器发来的消息
			//清空数据
			bzero(wbuf, sizeof(wbuf));
			recv(cfd, wbuf, sizeof(wbuf), 0);
 
			printf("收到的消息为:%s\n", wbuf);
		}
	}
 
	//5、关闭套接字
	close(cfd);
	return 0;
}

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

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

相关文章

【笔记】ArkTS 语言(OpenHarmony系统)

一、官方简介和文档 介绍&#xff1a;aArkTS 语言 | 华为开发者联盟 (huawei.com) 学习指南&#xff08;文档&#xff09;&#xff1a;初识ArkTS语言-学习ArkTS语言-入门 | 华为开发者联盟 (huawei.com) 二、ArkTS语言知识 &#xff08;一&#xff09;编程语言介绍 Mozilla创…

ASUS华硕天选2锐龙版笔记本电脑FA506ICB/FA706IC原装出厂Windows11系统,预装OEM系统恢复安装开箱状态

链接&#xff1a;https://pan.baidu.com/s/122iHHEOtNUu4azhVPnxNuA?pwdsqk7 提取码&#xff1a;sqk7 适用型号&#xff1a; FA506IM、FA506IE、FA506IC、FA506IHR FA506IR、FA506IHRB、FA506ICB、FA506IEB FA706IM、FA706IE、FA706IC、FA706IHR FA706IR、FA706IHRB、F…

DxO PureRAW:赋予RAW图像生命,打造非凡视觉体验 mac/win版

DxO PureRAW 是一款专为RAW图像处理而设计的软件&#xff0c;旨在帮助摄影师充分利用RAW格式的优势&#xff0c;实现更加纯净、细腻的图像效果。该软件凭借其强大的功能和易于使用的界面&#xff0c;成为了RAW图像处理领域的佼佼者。 DxO PureRAW 软件获取 首先&#xff0c;Dx…

python 操作 minio

座右铭&#xff1a;怎么简单怎么来&#xff0c;以实现功能为主。 欢迎大家关注公众号与我交流 环境安装 pip install -U minio 示例代码 import os from minio import Minio from loguru import logger from datetime import timedeltaclass Client:endpoint: ip:portaccess…

【笔记】Android 漫游定制SPN定制有关字段

一、SPN模块简介 【笔记】SPN和PLMN 运营商网络名称显示 Android U 配置 WiFiCalling 场景下PLMN/SPN 显示的代码逻辑介绍 【笔记】Android Telephony 漫游SPN显示定制&#xff08;Roaming Alpha Tag&#xff09; 二、相关配置字段 non_roaming_operator_string_array 是否…

Nginx使用—http基础知识

web访问流程 当我们在客户端通过浏览器输入网址的时候&#xff0c;这时候是访问不到服务器的&#xff0c; 先会去找到DNS解析服务器&#xff0c;DNS解析服务器返回IP地址&#xff0c; 客户端通过http协议向服务端发送请求&#xff0c;服务器响应请求并返回对应的资源给客户端&a…

【排序】详解冒泡排序

一、思想 冒泡排序的基本思想是利用两两比较相邻记录的方式&#xff0c;通过一系列的比较和交换操作&#xff0c;使得较大或较小的元素逐渐移动到数列的一端。在每一轮的排序过程中&#xff0c;都会从数列的起始位置开始&#xff0c;对相邻的元素进行比较&#xff0c;如果它们…

【论文笔记】Language Models are Unsupervised Multitask Learners

Language Models are Unsupervised Multitask Learners 回顾一下第一代 GPT-1 &#xff1a; 设计思路是 “海量无标记文本进行无监督预训练少量有标签文本有监督微调” 范式&#xff1b;模型架构是基于 Transformer 的叠加解码器&#xff08;掩码自注意力机制、残差、Layernorm…

linux系统---LNMP架构下部署社区论坛与博客

一.编译安装Nginx&#xff08;web服务器&#xff09; 1.关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 0 2、安装依赖包 yum -y install pcre-devel zlib-devel gcc gcc-c make 3、创建运行用户 nginx 服务程序默认 以 nobody 身份运行&a…

upload-Labs靶场“11-15”关通关教程

君衍. 一、第十一关 %00截断GET上传1、源码分析2、%00截断GET上传 二、第十二关 %00截断POST上传1、源码分析2、%00截断POST上传 三、第十三关 文件头检测绕过1、源码分析2、文件头检测绕过 四、第十四关 图片检测绕过上传1、源码分析2、图片马绕过上传 五、第十五关 图片检测绕…

CSS的标准文档流,web后端开发框架

了解校招 知己知彼才能百战百胜&#xff0c;在准备校招之前&#xff0c;我们先要了解校招。 什么是校招&#xff1f; 校招&#xff0c;全称校园招聘&#xff0c;指企业招聘那些即将毕业的学生。校招主要分为三个部分&#xff1a;简历筛选&#xff0c;笔试&#xff0c;面试。 …

MATLAB环境下基于LSTM模型的癫痫发作检测方法

癫痫预测研究是利用脑电信号对癫痫发病过程做出及时的预测以促进癫痫发病的防治&#xff0c;这一研究的重点在于充分利用癫痫发生前后人体大脑产生的脑电信号。但截至上世纪九十年代初期&#xff0c;医学工作者及相关领域的专家们仍然相信癫痫病的发生过程是一种突发的、毫无规…

el-dialog封装组件

父页面 <template><div><el-button type"primary" click"visible true">展示弹窗</el-button><!-- 弹窗组件 --><PlayVideo v-if"visible" :visible.syncvisible /></div> </template><sc…

Kafka数据推送配置 | 如何设置账号密码验证?

背景&#xff1a;之前资产信息用网络接口进行数据推送&#xff0c;但是接口推送需要验证而且反应较慢。Kafak中间件提供了另一种可行的数据推送方式&#xff0c;它可以进行消息队列推送&#xff0c;且反应速度快。但是Kafka需部署在公网环境&#xff0c;并进行登录验证&#xf…

笔记本小键盘怎么开?探索笔记本小键盘的奥秘

对于许多笔记本用户来说&#xff0c;小键盘&#xff08;也称为数字键盘或NumPad&#xff09;是一个不可或缺的工具&#xff0c;它为用户提供了快速输入数字和进行计算的便利。然而&#xff0c;并非所有的笔记本电脑都配备有物理小键盘&#xff0c;而且有时我们可能会发现小键盘…

对接华泰极速行情丨DolphinDB INSIGHT 插件使用教程

INSIGHT 是华泰证券依托大数据存储、实时分析等领域的技术积累&#xff0c;整合接入国内多家交易所高频行情数据&#xff0c;为投资者提供集行情接入、推送、回测、计算及分析等功能于一体的行情数据服务解决方案。基于 INSIGHT 官方提供的行情数据服务 C SDK&#xff08;TCP 版…

图像处理 mask掩膜

1&#xff0c;图像算术运算 图像的算术运算有很多种&#xff0c;比如两幅图像可以相加&#xff0c;相减&#xff0c;相乘&#xff0c;相除&#xff0c;位运算&#xff0c;平方根&#xff0c;对数&#xff0c;绝对值等&#xff1b;图像也可以放大&#xff0c;缩小&#xff0c;旋…

2023年全国职业院校技能大赛 GZ073网络系统管理赛项 模块A:网络构建

2023年全国职业院校技能大赛 GZ073网络系统管理赛项 模块A:网络构建 卷II 一. 拓扑图 二.有线网络配置 三.无线网络配置 四.出口网络配置 二、有线配置 S1.txt S1#show running-config Building configuration... Current configuration : 5008 bytes! version RGOS 10…

启英泰伦「离线自然说」:让照明语音交互更自然、更便捷

随着科技的不断发展&#xff0c;智能家居已经成为现代生活的一部分。其中&#xff0c;智能照明作为智能家居的重要组成部分&#xff0c;为人们带来了更加便捷、舒适的照明体验。然而&#xff0c;传统的离线语音交互技术在智能照明领域的应用一直受到词条存储量的限制&#xff0…

React轻松开发平台:实现高效、多变的应用开发范本

在当今快节奏的软件开发环境中&#xff0c;追求高效、灵活的应用开发方式成为了开发团队的迫切需求。React低代码平台崭露头角&#xff0c;为开发人员提供了一种全新的开发范式&#xff0c;让开发过程更高效、更灵活&#xff0c;从而加速应用程序的开发周期和交付速度。 1. 快…