【从零开始的嵌入式生活】网络编程3——并发服务器

简介: 【从零开始的嵌入式生活】网络编程3——并发服务器

今天正式继续网络编程,之前博主没怎么接触过网络编程,所以这部分会写的细一点,预计这部分是需要七天文章对应一星期的写作。希望有人愿意跟我一起学习呀。


🧑🏻作者简介:一个学嵌入式的年轻人

✨联系方式:2201891280(QQ)

📔源码地址:https://gitee.com/xingleigao/study_qianrushi

⏳全文大约阅读时间: 60min

文章目录

TCP并发服务器多线程

绑定的任意IP

网络鉴权

多线程编程

多进程编程

写在最后

TCP并发服务器多线程

在上次我们完成了一个基本的TCP的连接的架构,但是会出现很多问题,我们这次就进行一点点的优化,让它接近于真正的服务器的样子。


绑定的任意IP

上次我们书写的是127.0.0.1的地址,因为是本地回环地址,所以可以在任意服务器上运行,但是换一台电脑可能就连不上了,所以我们可以使用更加通用的方式。


sin.sin_addr.s_addr = htonl(INADDR_ANY);


我们可以使用上面的代码来绑定任意ip,其中INADDR_ANY是一个宏定义,其值为-1,也就是全1,也就是255.255.255.255也就是全网接收。

网络鉴权

上次我们没有理会accept的后两个参数,导致我们无法得知是谁在访问我们的服务器,我们就不能进行网络鉴权了,其实这个用的比较多,比如之前我写的爬虫有些网站直接封IP就是利用的这个方式。


 

struct sockaddr_in cin;
        socklen_t addrlen = sizeof(cin);
        if((newfd = accept(fd, (struct sockaddr *)&cin, &addrlen)) < 0){
                perror("accept");
                exit(1);
        }


上面的方式我们就可以通过cin来接收到IP地址,从而做判断过滤等操作啦。


多线程编程

之前我们学习过多线程编程,还是要使用的,所以我们进行一下优化,我直接给代码,大家可以看着理解消化一下。


#include <pthread.h>
#include "net.h"
void cli_data_handle(void * arg);
int main(void){
  //省略一万行
        /*优化3 : 用多线程来处理已建立好连接的*/
        struct sockaddr_in cin;
        socklen_t addrlen = sizeof(cin);
        pthread_t tid;
        while(1){
                 if((newfd = accept(fd, (struct sockaddr *)&cin, &addrlen)) < 0){
                        perror("accept");
                        exit(1);
                }
                char ip4_addr[16];
                if(!inet_ntop(AF_INET, (void *)&cin.sin_addr, ip4_addr, sizeof(cin))){
                        perror("inet_ntop");
                        exit(1);
                }
                printf("Client(%s:%d) is connected!\n", ip4_addr, htons(cin.sin_port));
                pthread_create(&tid, NULL, (void *)cli_data_handle, (void *)&newfd);
        };
        return 0;
}
void cli_data_handle(void * arg){
        int newfd = *(int *)arg;
        printf("handler thread:newfd = %d \n",newfd);
       //和newfd进行数据读写
        int ret = -1;
        char buf[BUFSIZ];
        while(1){
                bzero(buf, BUFSIZ);
                do{
                        ret = read(newfd, buf, BUFSIZ);
                }while(ret < 0 && EINTR == errno);
                if(ret < 0){
                        perror("read");
                        exit(1);
                }
                if(!ret){       //对方关闭
                        break;
                }
                printf("Receive data : %s\n",buf);
                if(!strncasecmp(buf, QUIT_STR, strlen(QUIT_STR))){ //用户退出
                       printf("Client(fd=%d) is exiting!\n",newfd);
                        break;
                }
        }
        close(newfd);
}


完整的代码在/6.network/1.API/server.c大家可以尝试运行。


多进程编程

多线程虽然可以满足基本要求,但是因为多线程的稳定性并没有那么高,因为如果进程如果死了就直接全死掉了,所以可以用多进程来写。因为这部分之前进行了学习,所以不会的建议翻一下回炉重造0.0,csdn不允许我放连接那我不放了,专栏里辛苦大家找一下吧。


   

/*多进程优化*/
        while(1){
                pid_t pid = -1;
                if((newfd = accept(fd, (struct sockaddr *)&cin, &addrlen)) <0){
                        perror("accept");
                        break;
                }
                /*创建一个子进程用于处理已建立的客户的交互数据*/
                if((pid = fork()) < 0){
                        perror("fork");
                        break;
                }
                if(0 == pid){//子进程中
                        close(fd);
                        char ip4_addr[16];
                        if(!inet_ntop(AF_INET, (void *)&cin.sin_addr, ip4_addr, sizeof(cin))){
                                perror("inet_ntop");
                                exit(1);
                        }
                        printf("Client(%s:%d) is connected!\n", ip4_addr, ntohs(cin.sin_port));
                        cli_data_handle(&newfd);
                        return 0;
                }else{//实际上 pid > 0 父进程中
                        close(newfd);
                }
        }


完整代码在6.network/1.API/server_fork.c中


写在最后

今天依旧还是网络编程,这部分非常重要,所有文件我都放在了gitee哦,需要自取,我尽量一天一更,大家和我一起变强呀!最后三连即可提高学习效率!!!


相关文章
|
4月前
|
机器学习/深度学习 人工智能 运维
企业内训|LLM大模型在服务器和IT网络运维中的应用-某日企IT运维部门
本课程是为某在华日资企业集团的IT运维部门专门定制开发的企业培训课程,本课程旨在深入探讨大型语言模型(LLM)在服务器及IT网络运维中的应用,结合当前技术趋势与行业需求,帮助学员掌握LLM如何为运维工作赋能。通过系统的理论讲解与实践操作,学员将了解LLM的基本知识、模型架构及其在实际运维场景中的应用,如日志分析、故障诊断、网络安全与性能优化等。
130 2
|
2月前
|
缓存 负载均衡 监控
HTTP代理服务器在网络安全中的重要性
随着科技和互联网的发展,HTTP代理IP中的代理服务器在企业业务中扮演重要角色。其主要作用包括:保护用户信息、访问控制、缓存内容、负载均衡、日志记录和协议转换,从而在网络管理、性能优化和安全性方面发挥关键作用。
95 2
|
4月前
|
存储 安全 数据可视化
提升网络安全防御有效性,服务器DDoS防御软件解读
提升网络安全防御有效性,服务器DDoS防御软件解读
98 1
提升网络安全防御有效性,服务器DDoS防御软件解读
|
3月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
1296 2
|
4月前
|
Kubernetes 应用服务中间件 nginx
搭建Kubernetes v1.31.1服务器集群,采用Calico网络技术
在阿里云服务器上部署k8s集群,一、3台k8s服务器,1个Master节点,2个工作节点,采用Calico网络技术。二、部署nginx服务到k8s集群,并验证nginx服务运行状态。
1409 1
|
4月前
|
安全 区块链 数据库
|
4月前
|
测试技术
评测 AlibabaCloud 阿里云国际版 香港轻量云服务器的性能和网络怎么样
评测 AlibabaCloud 阿里云国际版 香港轻量云服务器的性能和网络怎么样
|
2月前
|
SQL 安全 网络安全
网络安全与信息安全:知识分享####
【10月更文挑战第21天】 随着数字化时代的快速发展,网络安全和信息安全已成为个人和企业不可忽视的关键问题。本文将探讨网络安全漏洞、加密技术以及安全意识的重要性,并提供一些实用的建议,帮助读者提高自身的网络安全防护能力。 ####
86 17
|
2月前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。
|
2月前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
63 10

热门文章

最新文章