• 【嵌入式Linux系统开发】网络编程


    文章目录

    1.基本概念

    网络程序和普通程序最大的区别是,网络程序是由两个部分组成的,即客户端和服客户端的由务器端。网络程序是先服务器程序启动,等待客户端的程序运行并建立连接,一般来说,服务器的程序在一个端口上监听,直到有一个客户端的程序发来请求。

    1.1 OSI模型

    OSI模型是国际互联网标准化组织所定义的,目的是为了使网络的各个层次有标准。

    OSI模型共7个层次:

    (1)物理层:硬件连接的接口

    (2)数据链路层:负责实现通信信道的无差错传输,提供数据帧、差错控制、流量控制和链路控制等功能。

    (3)网络层:负责将数据正确迅速地从源主机传送到目的主机,其功能主要有寻址以及相关的流量控制和拥塞控制等。

    (4)传输层:为上层处理过程掩盖下层结构的细节,保证把会话层的信息有效地传输到另一方的会话层

    (5)会话层:提供服务请求者和提供者之间的通信,用以实现两端主机之间的会话管理、传输同步和活动管理等

    (6)表示层:主要功能是实现信息转换

    (7)应用层:为用户提供常用的应用

    1.2 常用命令
    • netstat

      命令netstat用于网络的连接、路由器和接口统计等网络的信息

      常用命令:netstat -an:用于显示详细的网络状态

    • telnet

      命令telnet是用来远程控制的程序,可以用该程序来调试用户的服务端程序

    1.3 网络地址

    网络地址是终端在整个网络中的唯一标识,

    1.4 IP设置项
    • IP地址:机器的唯一识别的网络地址
    • 网络广播地址
    • 子网掩码:用于——屏蔽IP网络的一部分、区分网络标识和主机标识、识别子网
    • 网关:用于访问外网
    • MAC地址:网卡的物理地址
    1.5 端口

    网络地址用来识别哪一台机器;端口用于识别一台机器的哪一个程序

    端口分类:

    • 公认端口:端口号为0~1023
    • 注册端口:端口号为1024~49151
    • 动态端口:端口号为49152~65535

    2.TCP/IP协议

    TCP/IP:传输控制协议/因特网互联协议,又叫网络通信协议

    2.1 整体架构概述

    TCP/IP 实际上一个协同工作的通信家族,为网络数据通信提供通路。为讨论方便可TCP/IP 协议组大体上分为三部分:

    • Internet 协议(IP)
    • 传输控制协议(TCP)和用户数据报协议(UDP)
    • 处于 TCP 和 UDP 之上的一组应用协议。它们包括:TELNET,文件传送协议(FTP),域名服务(DNS)和简单的邮件传送程序(SMTP)等

    在这里插入图片描述

    2.2 IP协议

    IP主要有以下四个主要功能:

    • 数据传送
    • 寻址
    • 路由选择
    • 数据报文的分段

    IP的主要目的

    为数据输入/输出网络提供基本算法,为高层协议提供无连接的传送服务。

    2.3 IP构成

    IP包由IP协议头与协议数据两部分构成。

    2.4 TCP协议

    TCP是重要的传输层协议,目的是允许数据同网络上的其他节点进行可靠的交换。它能提供端口编号的译码,以识别主机的应用程序,而且完成数据的可靠传输

    TCP 协议具有严格的内装差错检验算法确保数据的完整性。
    TCP 是面向字节的顺序协议,这意味着包内的每个字节被分配一个顺序编号,并分配给每包一个顺序编号。

    基于TCP连接的建立
    在这里插入图片描述

    2.5 UDP协议

    UDP也是传输层协议,它是无连接的,不可靠的传输服务。

    当接收数据时它不向发送方提供确认信息,它不提供输入包的顺序,如果出现丢失包或重份包的情况,也不会向发送方发出差错报文。
    由于它执行功能时具有较低的开销,因而执行速度比TCP快。

    基于UDP协议连接的建立

    3.Linux网络编程

    Linux中的网络编程通过Socket(套接字)接口实现,Socket是一种文件描述符

    3.1 类型

    套接字socket有三种类型:

    • 流式套接字(SOCK_STREAM)

    流式的套接字可以提供可靠的、面向连接的通讯流。它使用了TCP协议。TCP 保证了数据传输的正确性和顺序性

    • 数据报套接字(SOCK_DGRAM)

    数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的 ,并且不保证可靠,无差错,它使用数据报协议UDP。

    • 原始套接字

    原始套接字允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议的测试等

    3.2 函数使用

    进行Socket编程

    常用函数:

    • socket()

    创建一个socket(套接字)。

    • bind()

    用于绑定IP地址和端口号到socket。

    • connect()

    该函数用于绑定之后的client端,与服务器建立连接。

    操作函数:

    • listen()

    设置能处理的最大连接要求,Listen()并未开始接收连线,只是设置socket为listen模式。

    • accept()

    用来接受socket连接。

    • Send()

    发送数据

    • Recv()

    接收数据

    4.服务器模型

    在网络程序里面,一般来说都是许多客户对应一个服务器,为了处理客户的请求, 对服务端的程序就提出了特殊的要求。目前最常用的服务器模型有:

    • 循环服务器:服务器在同一个时刻只可以响应一个客户端的请求
    • 并发服务器:服务器在同一个时刻可以响应多个客户端的请求
    4.1 UDP循环服务器

    UDP循环服务器的实现方法:
    UDP服务器每次从套接字上读取一个客户端的请求->处理->然后将结果返回给客户机。

    socket(...); 
    bind(...);
    while(1)
    {
    	recvfrom(...); 
    	process(...);
    	sendto(...);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    因为UDP是非面向连接的,没有一个客户端可以老是占住服务端, 服务器对于每一个客户机的请求总是能够满足。

    4.2 TCP循环服务器

    TCP服务器接受一个客户端的连接,然后处理,完成了这个客户的所有请求后,断开连接。算法如下:

    socket(...);
    bind(...);
    listen(...);
    while(1)
    { 
    	accept(...);
    	process(...);
    	close(...);
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    TCP循环服务器一次只能处理一个客户端的请求。只有在这个客户的所有请求都满足后, 服务器才可以继续后面的请求。这样如果有一个客户端占住服务器不放时,其它的客户机都不能工作了,因此,TCP服务器一般很少用循环服务器模型的。

    4.3 TCP并发服务器

    并发服务器的思想是每一个客户机的请求并不由服务器直接处理,而是由服务器创建一个 子进程来处理。算法如下:

    socket(...);
    bind(...);
    listen(...);
    while(1)
    {
    	accept(...);
    	if(fork(..)==0)
    	{
    		process(...);
    		close(...);
    		exit(...);
    	}
    	close(...);
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    TCP并发服务器可以解决TCP循环服务器客户机独占服务器的情况。但同时也带来了问题:为了响应客户的请求,服务器要创建子进程来处理,而创建子进程是一种非常消耗资源的操作。

    5.多路复用IO

    1.设置要监控的文件

    2.调用Select开始监控

    3.判断文件是否发生变化

    阻塞函数在完成其指定的任务以前不允许程序继续向下执行。

    例如:当服务器运行到accept语句时,而没有客户请求连接,服务器就会停止在accept语句上等待连接请求的到来。这种情况称为阻塞(blocking)

    而非阻塞操作则可以立即完成。

    例如,如果你希望服务器仅仅检查是否有客户在等待连接,有就接受连接,否则就继续做其他事情,则可以通过使用select系统调用来实现。
    除此之外,select还可以同时监视多个套接字 。

    int select(int maxfd, fd_set *readfds, fd_set *writefds, fe_set *exceptfds, const struct timeval *timeout)
    
    • 1
    • Maxfd: 文件描述符的范围,比待检的最大文件描述符大1
    • Readfds:被读监控的文件描述符集
    • Writefds:被写监控的文件描述符集
    • Exceptfds:被异常监控的文件描述符集
    • Timeout:定时器

    系统提供了4个宏对描述符集进行操作:

    #include  
    void FD_SET(int fd, fd_set *fdset)
    void FD_CLR(int fd, fd_set *fdset)
    void FD_ZERO(fd_set *fdset)
    void FD_ISSET(int fd, fd_set *fdset)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    FD_SET将文件描述符fd添加到文件描述符集fdset中;
    FD_CLR从文件描述符集fdset中清除文件描述符fd;
    FD_ZERO清空文件描述符集fdset;
    在调用select后使用FD_ISSET来检测文件描述符集fdset中的文件fd发生了变化。

    实例:

    FD_ZERO(&fds); //清空集合
    sock1 = socket(……);
    sock2 = socket(……);
    bind(sock1,…);
    bind(sock2,…);
    listen(sock1,…);
    listen(sock1,…);
    FD_SET(sock1,&fds); //设置描述符
    FD_SET(sock2,&fds); //设置描述符 
    maxfdp=(sock1>sock2?sock1:sock2) + 1;
    switch(select(maxfdp,&fds,NULL,NULL,&timeout))
    	case -1: exit(-1);break; //select错误,退出程序
    	case 0:break;
    	default:
    		if(FD_ISSET(sock1,&fds)) //测试sock1是否可读	
    		accpet(sock1,…)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    打穿你的内网之三层内网渗透
    时序预测 | MATLAB实现GM(1,1)灰色时间序列预测
    SQL练习题:连续登录5天的活跃用户
    南美智利市场最全分析开发攻略,收藏一篇就够了
    Aspose.GIS 22.11.0 for .NET Crack
    关于解决跨域的几种方式
    【网络安全入门】学习网络安全必须知道的100 个网络基础知识
    安卓逆向之雷电模拟器中控
    SCT71403F50,SCT71403F33,TPS7B82,TPS7B81
    服务器硬件基础知识
  • 原文地址:https://blog.csdn.net/m0_67393157/article/details/126553369