LINUX 入门 8

LINUX 入门 8

day10 20240507 耗时:90min 有点到倦怠期了

课程链接地址

第8章 TCP服务器

1 TCP服务器的介绍

开始讲服务器端,之前是客户端DNS+https请求

  1. 基础:网络编程
  2. 并发服务器:多客户端
    1. 一请求,一线程 veryold
    2. IO多路复用,epoll/select上一章讲过了
  3. TCP server百万级连接

借助netassist.exe

2 TCP并发网络网络编程 一请求一线程

tcp server类似酒店迎宾领过去,监听listen

server有对应客户端的连接有socket 连接类似服务员点菜

没懂好多用法

  1. void *client_routine(void *arg){
        int clientfd = *(int *) arg;
    } 
    

    这是一个使用多线程处理客户端请求的例子。在这个例子中,每个客户端连接都会创建一个新的线程,并且通过 client_routine 函数进行处理。

    下面是对提供的代码片段的解释:

    • void *client_routine(void *arg) 是一个线程函数,用于处理单个客户端连接。
    • int clientfd = *(int *) arg; 将传入参数 arg 解引用为整数类型,并将其赋值给 clientfd 变量。假设传入参数是一个指向整数类型的指针,即客户端套接字描述符。 *(int *) arg;它首先将 arg 强制转换为指向整数的指针,然后使用解引用操作符 * 获取该指针所指向的值。

    你可以在该函数中编写适当的代码来处理客户端请求,例如读取和发送数据等操作。请注意,在每个线程内部需要负责释放相关资源并确保线程安全性。

步骤:

gcc -o tcp_server tcp_server.c -lpthread
./tcp_server 8888

服务器就起来了

打开netassist 改远程地址: 192.168.243.128:8888

在这里插入图片描述

有bug连上了,但是点发送以后收不到!!!

或者是bind error, 没调出来,可能那里打错了,老师的是可以的

  1. 起多个客户端send,如何取区分

    sockfd无法解决,需要应用协议发的内容不同<fromid: xxxx>

  2. 缺点:不适合超多client,内存不够; 用epoll改

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <pthread.h>

#include <errno.h>
#include <fcntl.h>

#include <sys/epoll.h>
#include <unistd.h> //close要


#define BUFFER_LENGTH 1024

// 法一 一请求一线程
void *client_routine(void *arg){
    int clientfd = *(int *) arg;
    while(1){
        char buffer[BUFFER_LENGTH] = {0}; 
        // 用于从客户端套接字中接收数据并将其存储到缓冲区中。clientfd:表示要接收数据的套接字文件描述符。buffer:表示接收数据的缓冲区,也就是存放接收到的数据的位置。BUFFER_LENGTH:表示期望接收的最大字节数,即缓冲区的大小。0:表示额外选项,通常设置为 0。
        int len = recv(clientfd, buffer, BUFFER_LENGTH, 0);
        if(len < 0){
            // 没数据,如果阻塞,就是一直等,返回-1
            // 在非阻塞 I/O 模式下,当没有可用数据时,recv() 函数可能返回 -1 并设置 errno 为 EAGAIN 或 EWOULDBLOCK。这表示当前没有数据可供接收,并且稍后可能会有更多数据可用。因此,这段代码的作用是检测 errno 是否等于 EAGAIN 或 EWOULDBLOCK,以判断是否需要继续等待更多数据的到达。
            if(errno == EAGAIN ||errno == EWOULDBLOCK){
                close(clientfd);
                break;
            }else if(len == 0){ //disconnect
                close(clientfd);
                break;
            }else{
                printf("recv: %s, %d byte(s)\n",buffer, len);
            }
        }
    }
} 

// 1 socket创建
int main(int argc, char*argv[]){
    if(argc<2) {
        printf("param error\n");
        return -1;
    }

    int port = atoi(argv[1]);

    int sockfd = socket(AF_INET, SOCK_STREAM, 0); //聘请一个迎宾的listen

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_family  = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY; //任意地址不确定

    // 0成功 1失败
    // 函数bind()将套接字与特定的IP地址和端口号进行绑定,以便后续接收来自该地址的连接请求。
    // 而listen()则表示开始监听连接请求,并指定最大允许等待连接队列的长度为5。这意味着服务器可以同时处理5个未处理的连接请求,超过这个数量的请求将被拒绝或排队等待处理。
    if(bind(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0){
        perror("bind error");
        return -2;
    }
    if(listen(sockfd, 5) < 0){
        perror("listen error");
        return -3;
    } 

    // 2迎宾sockfd 一直等着 为客户client介绍服务员socket
    while(1){
        struct sockaddr_in client_addr;
        memset(&client_addr, 0, sizeof(struct sockaddr_in));
        
        socklen_t client_len = sizeof(client_addr);
        
        // 使用accept函数接受来自服务器监听套接字 sockfd 的客户端连接请求,并将客户端的地址信息存储在名为 client_addr 的结构体中。
        int clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len); 

        // 法一 一请求一线程
        // 请求来了创建线程
        pthread_t thread_id;
        pthread_create(&thread_id, NULL, client_routine, &clientfd);
    }



}

3 TCP并发网络编程io多路复用epoll 水平触发与边沿触发

没敲,就看了一下

  1. what is epoll

    超多clients 对server发request

    检测到哪个client发了数据

    1. epoll_create
    2. epoll_ctl control管理 增删改
    3. epoll_wait() 多长时间去一次
#if 0

	while (1) {

		struct sockaddr_in client_addr;
		memset(&client_addr, 0, sizeof(struct sockaddr_in));
		socklen_t client_len = sizeof(client_addr);

		int clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);
		
		pthread_t thread_id;
		pthread_create(&thread_id, NULL, client_routine, &clientfd);

	}
	
#else

	int epfd = epoll_create(1);  
	struct epoll_event events[EPOLL_SIZE] = {0};

	struct epoll_event ev;
	ev.events = EPOLLIN; 
	ev.data.fd = sockfd;
	epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);

	
	while (1) {

		int nready = epoll_wait(epfd, events, EPOLL_SIZE, 5); // -1, 0, 5
		if (nready == -1) continue;

		int i = 0;
		for (i = 0;i < nready;i ++) {

			if (events[i].data.fd == sockfd) { // listen 

				struct sockaddr_in client_addr;
				memset(&client_addr, 0, sizeof(struct sockaddr_in));
				socklen_t client_len = sizeof(client_addr);

				int clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);

				ev.events = EPOLLIN | EPOLLET; 
				ev.data.fd = clientfd;
				epoll_ctl(epfd, EPOLL_CTL_ADD, clientfd, &ev);

			} else {

				int clientfd = events[i].data.fd;
				
				char buffer[BUFFER_LENGTH] = {0};
				int len = recv(clientfd, buffer, BUFFER_LENGTH, 0);
				if (len < 0) {
					close(clientfd);

					ev.events = EPOLLIN; 
					ev.data.fd = clientfd;
					epoll_ctl(epfd, EPOLL_CTL_DEL, clientfd, &ev);
					
				} else if (len == 0) { // disconnect
					close(clientfd);

					ev.events = EPOLLIN; 
					ev.data.fd = clientfd;
					epoll_ctl(epfd, EPOLL_CTL_DEL, clientfd, &ev);
					
				} else {
					printf("Recv: %s, %d byte(s)\n", buffer, len);
				}
				
				
			}

		}

	}
	

#endif
	

一边听,敲,记笔记云里雾里的

  1. 关于io有无数据?如何检测 epoll_wait
    1. 有1 无0
    2. 一种是水平触发EPOLLIN:有没有;一种是边沿触发EPOLLET:检测从无变有

**面试重点:**epoll两种触发,reactor,协程,epoll 在sockfd set集合里

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

推荐网站(6)33台词,通过台词找电影、电视剧、纪录片等素材

今天推荐一个网站33台词&#xff0c;你可以根据电影、电视剧、纪录片等某一段台词&#xff0c;来找到来源&#xff0c;帮你精确到多少分多少秒出现的&#xff0c;非常的好用&#xff0c;尤其是对那种只记得一些经典台词&#xff0c;不知道是哪个电影的人来说&#xff0c;帮助巨…

揭秘全网热门话题:抖音快速涨粉方法,巨量千川投流助你日增10000粉

在当今社交媒体的时代( 千川投流&#xff1a;hzzxar&#xff09;抖音成为了年轻人分享自己才华和生活的平台。然而&#xff0c;要在抖音上快速获得关注和粉丝&#xff0c;却不是一件容易的事情。今天&#xff0c;我们将揭秘全网都在搜索的抖音快速涨1000粉的秘籍&#xff0c;带…

网络文件共享

存储类型分三类 直连式存储&#xff1a;DAS存储区域网络&#xff1a;SAN网络附加存储&#xff1a;NAS 三种存储架构的应用场景 DAS虽然比较古老了&#xff0c;但是还是很适用于那些数据量不大&#xff0c;对磁盘访问速度要求较高的中小企业SAN多适用于文件服务器&#xff0c…

pyfilesystem2,一个超级实用的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个超级实用的 Python 库 - pyfilesystem2。 Github地址&#xff1a;https://github.com/pyfilesystem/pyfilesystem2 PyFilesystem2是一个强大的Python库&#xff0c;用于抽象化文件系统操作。它…

静态分析-RIPS-源码解析记录-02

这部分主要分析scanner.php的逻辑&#xff0c;在token流重构完成后&#xff0c;此时ini_get是否包含auto_prepend_file或者auto_append_file 取出的文件路径将和tokens数组结合&#xff0c;每一个文件都为一个包含require文件名的token数组 接着回到main.php中&#xff0c;此时…

【GUI软件】调用YouTube的API接口,采集关键词搜索结果,并封装成界面工具!

文章目录 一、背景介绍1.1 爬取目标1.2 演示视频1.3 软件说明 二、代码讲解2.1 调用API-搜索接口2.2 调用API-详情接口2.3 API_KEY说明2.4 软件界面模块2.5 日志模块 三、获取源码及软件 一、背景介绍 1.1 爬取目标 您好&#xff01;我是马哥python说&#xff0c;一名10年程序…

动态规划day.2

62.不同路径 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#…

能否直接上手 Qt ?——看完 C++ 课本后怎么做?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Qt的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;如果你已经阅读了 C 课本&#xff0c;但仍然感到…

TMS320F28335学习笔记-时钟系统

第一次使用38225使用了普中的clocksystem例程进行编译&#xff0c;总是编译失败。 问题一&#xff1a;提示找不到文件 因为工程的头文件路径没有包含&#xff0c;下图的路径需要添加自己电脑的路径。 问题二 找不到库文件 例程种的header文件夹和common文件夹不知道从何而来…

7.删除有序数组中的重复项(快慢指针)

文章目录 题目简介题目解答解法一&#xff1a;暴力解法复杂度分析&#xff1a; 解法二&#xff1a;双指针(快慢指针)代码&#xff1a;复杂度分析&#xff1a; 题目链接 大家好&#xff0c;我是晓星航。今天为大家带来的是 相关的讲解&#xff01;&#x1f600; 题目简介 题目解…

【C语言 | 字符串处理】sscanf 详细介绍、使用说明以及使用例子源码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-05-08 1…

【Python爬虫】使用request和xpath爬取高清美女图片

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 &#x1f388; urlib.request &#x1f525;具体的方法 ✈ lxml &#x1f525;xpath的基本语法 1. 基本路径 2. 选择节点 3. 谓语&#xff08;Predicates&#xff09; 4. 通配符 5. 选择多个路径 6. 函数 …

OV证书——企业网站的第一选择

据官方数据统计&#xff0c;从2024年开始OV证书的签发量远远超过DV证书的签发量&#xff0c;越来越多的企业网站摒弃了基础的DV证书&#xff0c;选择更高级别的OV证书。 但是其价格相对于DV证书来说要高几百甚至上千元&#xff0c;这里推荐性价比很高的JoySSL&#xff0c;他们…

邦注科技给您解答 什么是注塑机模具保护器

模具监视器&#xff0c;这位制造业的守护神&#xff0c;时刻注视着模具的每一个细微变化。它的工作原理如同一位细心的侦探&#xff0c;利用传感器、数据采集系统和监控软件组成的精良装备&#xff0c;探寻模具的秘密。 传感器如同模具的耳目&#xff0c;敏锐地捕捉着模具的温度…

Elasticsearch的使用

Elasticsearch 1、认识和安装 Elasticsearch的官方网站如下&#xff1a; https://www.elastic.co/cn/elasticsearch Elasticsearch是由elastic公司开发的一套搜索引擎技术&#xff0c;它是elastic技术栈中的一部分。完整的技术栈包括&#xff1a; Elasticsearch&#xff1…

Ps 滤镜:渲染

Ps菜单&#xff1a;滤镜/渲染 Filter/Render “渲染”子菜单中的滤镜主要用于生成或模拟各种自然和抽象的视觉效果&#xff0c;这些效果通常很难通过传统的摄影或手绘技术实现。这类滤镜能够为设计师和艺术家提供强大的工具&#xff0c;以增强图像的视觉冲击力、创造性或实现特…

11.偏向锁原理及其实战

文章目录 偏向锁原理及其实战1.偏向锁原理2.偏向锁案例代码演示2.1.偏向锁案例代码2.2.1.无锁情况下状态2.1.2.偏向锁状态2.1.3.释放锁后的状态 2.2.偏向锁的膨胀和撤销2.2.1.偏向锁撤销的条件2.2.2.偏向锁的撤销 2.2.3.偏向锁的膨胀 2.3.全局安全点原理和偏向锁撤销性能问题2.…

Electron项目中将CommonJS改成使用ES 模块(ESM)语法preload.js加载报错

问题 将Electron项目原CommonJS语法改成使用ES 模块&#xff08;ESM&#xff09;语法&#xff0c;preload.js一直加载不到&#xff0c;报错如下&#xff1a; VM111 renderer_init:2 Unable to load preload script: D:\Vue\wnpm\electron\preload.js VM111 renderer_init:2 E…

今日刷三题(day11):不同路径的数目(一)+短距离最小路径和+把数字翻译成字符串

题目一&#xff1a;不同路径的数目&#xff08;一&#xff09; 题目描述&#xff1a; 一个机器人在mn大小的地图的左上角&#xff08;起点&#xff09;。机器人每次可以向下或向右移动。机器人要到达地图的右下角&#xff08;终点&#xff09;。可以有多少种不同的路径从起点…

全栈开发之路——前端篇(6)生命周期和自定义hooks

全栈开发一条龙——前端篇 第一篇&#xff1a;框架确定、ide设置与项目创建 第二篇&#xff1a;介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇&#xff1a;setup语法&#xff0c;设置响应式数据。 第四篇&#xff1a;数据绑定、计算属性和watch监视 第五篇 : 组件…