网络编程 day 5

news2024/11/19 4:26:06

1、根据select TCP服务器流程图编写服务器

#include <myhead.h>

#define ERR_MSG(msg)  do{\
    fprintf(stderr, "__%d__:", __LINE__); \
    perror(msg);\
}while(0)

#define PORT 8888               //端口号,范围1024~49151
#define IP  "192.168.114.72"   //本机IP,ifconfig


int main(int argc, const char *argv[])
{
    //创建流式套接字 socket
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("socket create success sfd=%d\n", sfd);

    //允许端口快速的被复用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("允许端口快速的被复用成功\n");


    //填充地址信息结构体给bind函数绑定,
    //真实的地址信息结构体根据地址族指定 AF_INET:man 7 ip
    struct sockaddr_in sin;
    sin.sin_family      = AF_INET;      //必须填AF_INET;
    sin.sin_port        = htons(PORT);  //端口号的网络字节序
    sin.sin_addr.s_addr = inet_addr(IP);//本机IP


    //绑定服务器的地址信息---> 必须绑定 bind
    if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
    {
        ERR_MSG("bind");
        return -1;
    }
    printf("bind success\n");


    //将套接字设置为被动监听状态 listen
    if(listen(sfd, 128) < 0)
    {
        ERR_MSG("listen");
        return -1;
    }
    printf("listen success\n");

	//创建一个读集合
	fd_set readfds,tempfds;

	//清空集合
	FD_ZERO(&readfds);

	//将需要监测的文件描述符添加到集合中
	FD_SET(0,&readfds);
	FD_SET(sfd,&readfds);

	int maxfd = sfd;    //存储最大的文件描述符

	int s_res = -1;
	ssize_t res = -1;
    char buf[128] = "";
	int newfd = -1;
	struct sockaddr_in cin;           //存储客户端的地址信息
	socklen_t addrlen = sizeof(cin);  //真实的地址信息结构体的大小

	while(1)
    {
       tempfds = readfds;
	   //执行IO多路复用函数
	   s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);

		//进行判断
		if(s_res < 0)
        {
            ERR_MSG("select");
            return -1;
        }
        else if(0 == s_res)
        {
            printf("time out\n");
			break;
		}

		printf("_%d_\n",__LINE__);



		//能运行到当前位置,则代表select函数解除阻塞
		//此时集合中会只剩下产生事件的文件描述符
		//0号准备就绪,则集中会只剩下0号
		//sfd准备就绪,则集合中会只剩下sfd
		//0和sfd均准备就绪,则集中会剩下0和sfd;
		//只需要判断集合中剩下哪个文件描述符,走对应处理函数即可
		

		if(FD_ISSET(0,&tempfds))
		{
			printf("触发键盘输入事件\n");
			bzero(buf,sizeof(buf));
			fgets(buf,sizeof(buf),stdin);
			buf[strlen(buf)-1] = 0;

			printf(":%s\n",buf);

		}
			//判断sfd是否在文件集合中
		if(FD_ISSET(sfd,&tempfds))
		{
			printf("触发客户端连接事件\n");
			newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);
			if(newfd < 0)
			{
				ERR_MSG("newfd");
				return -1;
			}
			printf("[%s:%d]客户端连接成功 newfd=%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);
			
			FD_SET(newfd,&readfds);    //将newfd添加到集合中

			maxfd = maxfd>newfd ? maxfd:newfd; //更新maxfd
		}

	//除了0和sfd事件外,其余均为newfd对应的客户端交互事件
	//通过循环i,遍历所有newfd是否在tempfds中。
	

	for(int i=4; i<=maxfd; i++)
	{
		if(FD_ISSET(i,&tempfds))
		{
			printf("触发客户端交互事件\n");
			bzero(buf,sizeof(buf));
			//接收
			res = recv(i,buf,sizeof(buf),0);
			if(res < 0)
			{
				ERR_MSG("recv");
				return -1;

			}
			else if(0 == res)
			{
				printf("[%s;%d]客户端下线 newfd=%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),i);
				//关闭文件描述符
				close(i);
				//将文件描述符从集合中剔除
				FD_CLR(i,&readfds);
				continue;
			}

			printf("[%s:%d]newfd=%d ; %s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),i,buf);

			//发送
			strcat(buf,"*_*");
			if(send(i,buf,sizeof(buf),0) <0 )
			{
				ERR_MSG("send");
				return -1;
			}
			printf("send success\n");
			}
		}
	}
	//关闭文件名描述符
	if(close(sfd) < 0)
	{
		ERR_MSG("close");
		return -1;
	}

	return 0;
}


2、思维导图

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

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

相关文章

Mysql死锁卡死

查询 show processlist是显示用户正在运行的线程 show processlist;删除卡死的进程id kill 110651;

2023年最新项目追踪工具排行榜发布!

项目跟踪是确保项目顺利交付的重要环节&#xff0c;项目跟踪可以提高团队协作、管理项目风险、控制项目进度。不过对于项目经理而言&#xff0c;如何高效进行项目追踪工作并不是件轻松的工作。 项目跟踪工具的出现&#xff0c;减缓了项目经理的压力&#xff0c;它帮助团队监控…

适配ADRC自抗扰控制算法的MFP450-ADRC 套件焕新而来

关注 FMT 开源自驾仪的开发者可能知道&#xff0c;早在 2018 年 7 月 FMT开源自驾仪的早期版本就已经实现了 ADRC 算法。 经过几年的发展&#xff0c;FMT 在自抗扰控制算法的适配上做了进一步的优化&#xff0c;为了方便科研工作者和开发者快速上手&#xff0c;我们针对搭载 F…

静态代码检查工具PMD安装、使用

介绍 PMD官网&#xff1a;https://pmd.github.io/ 文档&#xff1a;https://docs.pmd-code.org/latest/ https://docs.pmd-code.org/latest/pmd_languages_java.html Java检查规则&#xff1a;https://docs.pmd-code.org/pmd-doc-7.0.0-rc3/pmd_rules_java.html PMD是一款可扩…

掌握这个工具,轻松管理所有物流信息

在电子商务高度发达的今天&#xff0c;物流快递行业在全球范围内发挥着至关重要的作用。然而&#xff0c;在如此复杂的物流环境中&#xff0c;快递退回件的管理和查询成为了一个难题。为了解决这个问题&#xff0c;我们有一个神奇的工具——快递批量查询高手。 快递批量查询高…

OpenGL-入门-BMP像素图glReadPixels(2)保存显示的界面

用glReadPixels保存显示的界面 #include <GL/glut.h> #include <iostream> #include <fstream> #include <vector>// Save pixel data as BMP image void saveBMP(const std::string& filename, int width, int height, const std::vector<GLu…

OA项目之左侧菜单动态选项卡

目录 1.左侧导航 参考地址&#xff1a;http://layui.org.cn/doc/element/nav.html 2.导入数据表及无限级分类 1) 数据导入&#xff08;此步骤在第一次文章已完成&#xff09; 2) 无限级分类&#xff1a;父亲找儿子的过程&#xff0c;将对应的儿子放在父亲下面&#xff0c;形…

无涯教程-Flutter - 简介

Flutter是一个由谷歌开发的开源移动应用软件开发工具包&#xff0c;用于为Android、iOS、 Windows、Mac、Linux、Google Fuchsia开发应用。 通常&#xff0c;创建移动应用程序是一个非常复杂和具有挑战性的任务。有许多框架可用&#xff0c;它提供了开发移动应用程序的出色函数…

yolov5的pytorch配置

1. conda create -n rdd38 python3.82、pip install torch1.8.0 torchvision0.9.0 torchaudio0.8.0 -f https://download.pytorch.org/whl/cu113/torch_stable.html -i https://pypi.tuna.tsinghua.edu.cn/simple 3、conda install cudatoolkit10.2

Flutter的未来与趋势,23年还学吗?

随着移动应用市场的不断扩大&#xff0c;跨平台开发框架的需求也越来越大。Flutter框架可以帮助开发者在不同平台上快速开发高质量的移动应用程序&#xff0c;这种趋势将进一步推动Flutter的发展和普及。 作为一名前端开发工程师&#xff0c;学习Flutter框架是非常有必要的。因…

NameError: name ‘_mysql‘ is not defined

报错信息 Traceback (most recent call last):File "/Users/xuruilong/Desktop/cmabc_back/.enve/lib/python3.9/site-packages/MySQLdb/__init__.py", line 18, in <module>from . import _mysql ImportError: dlopen(/Users/xuruilong/Desktop/cmabc_back/.…

报文信息转换器

HttpMessageConverter HttpMessageConverter:报文信息转换器&#xff0c;将请求报文转换为Java对象&#xff0c;或将Java对象转换为响应报文。它提供了两个注解和两个类型&#xff1a; RequestBody, ResponseBody, RequestEntity, ResponseEntity(响应用的较多) 准备 创建模块并…

HCIP学习--扩展知识点

端口镜像-SPAN 抓包软件只能抓取经过本地的网卡的流量 也就是抓取流量只能抓取本设备的流量 [r1]observe-port interface GigabitEthernet 0/0/2 定义一个SPAN的会话&#xff0c;然后定义监控接口&#xff08;也就是你要用的接口&#xff0c;你连接这个接口来对其他接口抓包…

IDEA批量处理行尾注释

前言 行尾注释写起来比较方便&#xff0c;所以很多时候我们都会习惯把注释写在行尾。 但这个是不符合编程规范的&#xff0c;写的代码注释主要是给后续接手人进行阅读帮助的。按照正常的阅读方式都是先读注释&#xff0c;然后再看代码&#xff0c;如果先看代码再看注释&#…

创建智能问答机器人:上线智能机器人客服,实时为客户提供解决方案

随着企业扩大规模和业务增长&#xff0c;客户咨询和服务请求增加。传统人工客服难以处理大量咨询&#xff0c;而智能化的AI客服可以同时满足多个客户需求。 智能问答机器人 创建智能问答机器人后&#xff0c;能自动化处理大量客户咨询&#xff0c;显著降低企业运营成本&#xf…

Multimedia-播放器-架构1

目录 引言 概念 播放器 播放器的工作流程 播放器的架构 IO模块 Parser&Demuxer模块 Decoder模块 渲染模块 小结 引言 什么是播放器&#xff1f; 播放器是做什么的&#xff1f;怎么做的&#xff1f; 概念 播放器 可以指软件&#xff0c;也可以指硬件 软件&am…

代码随想录算法训练营之JAVA|第四十一天|139. 单词拆分

今天是第 天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天。 算法挑战链接 139. 单词拆分https://leetcode.cn/problems/word-break/ 第一想法 看完之后完全没有想法。 看完代码随想录之后的想法 这是一个完全背包的问题&#xff0c;使用完全背包的解法。 单词就…

「C++程序设计 (面向对象进阶)」学习笔记・一

0、引言 本专栏的系列文章是在学习 北京邮电大学 崔毅东 老师的《C程序设计 (面向对象进阶)》课程过程中整理的。欢迎前往专栏了解更多相关内容~ &#x1f600; 有关于现代 C 的基本介绍&#xff0c;请前往《现代C基本介绍》&#xff01; &#x1f514; 先决条件 本专栏的系列…

微信小程序发布一个npm包

参考:https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html 同npm一样流程 npm install weixin_heath_apis