06 Linux编程-网络编程

1、为什么需要网络编程        

        管道、消息队列、共享内存、信号、信号量的IPC都是依赖于系统内核的,因此这些方式无法进行多机间(例如:linux与android、linux与单片机等)的通信。

        网络编程是基于网络的,因此需要网络地址(IP地址和端口号),数据交流协议(http、tcp/udp等)。socket套接字,一般都是用到tcp(可靠的、面向连接、类似于打电话)、udp(不可靠的、面向内容、类似于发短信)协议。

2、端口号的作用

        一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等。

        这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP地址与网络服务的关系是一对多的关系。

        实际上是通过“IP地址+端口号”来区分不同的服务的。

        端口提供了一种访问通道,服务器一般都是通过知名端口号来识别的。例如,对于每个TCP/IP实现来说,FTP服务器的TCP端口号都是21,每个Telnet服务器的TCP端口号都是23,每个TFTP(简单文件传送协议)服务器的UDP端口号都是69。

3、TCP/UDP对比

        (1)TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。

        (2)TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。

        (3)TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向内容的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)。

        (4)每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。

        (5)TCP首步开销20字节;UDP的首步开销小,只有8个字节

        (6)TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。

4、字节序

        字节序是指多字节数据在计算机内存中存储或网络传输时各字节的存储顺序。

        小端字节序(Little Endian):将低序字节存储在起始地址

        大端字节序(Big Endian):将高序字节存储在起始地址

        网络字节序是大端字节序,而x86系列CPU都是小端字节序。

4.1 字节序转换API

#include <netinet/in.h>//函数原型
uint16_t htons(uint16_t host16bitvalue);    //返回网络字节序的值
uint32_t htonl(uint32_t host32bitvalue);    //返回网络字节序的值
uint16_t ntohs(uint16_t net16bitvalue);     //返回主机字节序的值
uint32_t ntohl(uint32_t net32bitvalue);     //返回主机字节序的值//h代表host,n代表net,s代表short(两个字节),l代表long(4个字节)
//通过上面的4个函数可以实现主机字节序和网络字节序之间的转换
//有时可以用INADDR_ANY,INADDR_ANY指定地址让操作系统自己获取

5、socket开发步骤

        服务端:指定TCP/UDP、设置ip地址、设置端口号、监听

        客户端:获取服务器ip、获取服务器端口、连接

        (1)创建套接字

        (2)为套接字添加信息(IP地址和端口号)

        (3)监听网络连接

        (4)监听到有客户端接入,接受一个连接

        (5)数据交互

        (6)关闭套接字,断开连接 

6、相关API

6.1 创建套接字

//函数原型
int socket(int domain, int type, int protocol);

        (1)domain参数:指明所使用的协议族,通常为AF_INET,表示互联网协议族(TCP/IP协议族)。

                AF_INET               IPv4因特网域

                AF_INET6             IPv6因特网域

                AF_UNIX               Unix域

                AF_ROUTE           路由套接字

                AF_KEY                密钥套接字

                AF_UNSPEC        未指定

        (2)type参数:指定socket的类型

                SOCK_STREAM:流式套接字提供可靠的、面向连接的通信流;它使用TCP协议,从而保证了数据传输的正确性和顺序性。

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

                SOCK_RAM:允许程序使用低层协议,原始套接字允许对底层协议如IP或ICMP进行直接访问,功能强大但使用较为不便,主要用于一些协议的开发。

        (3)protocol参数:通常赋值为“0”

                0 选择type类型对应的默认协议

                IPPROTO_TCP        TCP传输协议

                IPPROTO_UDP        UDP传输协议

                IPPROTO_SCTP      SCTP传输协议

                IPPROTO_TIPC        TIPC传输协议

6.2 端口号函数

#include <sys/types.h>        /* See NOTES */
#include <sys/socket.h>//函数原型
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);//ipv4对应的是
struct sockaddr{unsigned short as_family;    //协议族char           as_data[14];  //IP+端口
}
//同等替换
struct sockaddr_in{as_family    sin_family;    //协议族in_port_t    sin_port;      //端口号struct in_addr sinaddr;    //IP地址结构体unsigned char sin_zero[8];    //填充,没有实际意义,只是为根sockaddr结构在内存中对齐,这样两者才能相互转换
}

         bind函数用于绑定IP地址和端口号到socketfd。

        (1)sockfd参数:是一个socket描述符

        (2)addr参数:是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针,指向要绑定给sockfd 的协议地址结构,这个地址结构根据地址创建socket时的地址协议族的不同而不同。

        如果要在linux中查找sockaddr_in函数,可以去/usr/include/路径下查找,输入命令:

#使用grep 检索 struct sockaddr_in函数定义的地方
#* 在当前目录下,n 显示行号,i 不区分大小写,r 递归查找
grep "struct sockaddr_in {" * -nir

6.3 地址转换

//函数原型//把字符串形式的“192.168.1.123”转为网络能识别的格式
int inet_aton(const char* straddr,struct in_addr *addrp);//把网络格式的ip地址转为字符串形式
char* inet_ntoa(struct in_addr inaddr); 

 6.4 监听设置函数

#include <sys/types.h>    /* See NOTES*/
#include <sys/socket.h>//函数原型
//coskfd 是socket系统调用返回的服务器端socket描述符
//backlog 指定在请求队列中允许的最大请求数
int listen(int sockfd, int backlog);

        通过listen函数可以设置能处理的最大连接数,listen()并未开始接受连线,只是设置sockect的listen模式,listen函数只用于服务器端,服务器进程不知道要与谁连接,因此,它不会主动地要求与某个进程连接,只是一直监听是否有其他客户进程与之连接,然后响应该连接请求,并对它做出处理,一个服务进程可以同时处理多个客户进程的连接。主要就两个功能:将一个未连接的套接字转换为一个被动套接字(监听),规定内核为相应套接字排队的最大连接数。

        内核为任何一个给定监听套接字维护两个队列:

                未完成连接队列,每个这样的 SYN 报文段对应其中一项:已由某个客户端发出并到达服务器,而服务器正在等待完成相应的TCP三次握手过程。这些套接字处于SYN_REVD状态;

                已完成连接队列,每个已完成 TCP三次握手过程的客户端对应其中一项。这些套接字处于ESTABLISHED状态。

6.5 连接函数 

#include <sys/types.h>    /* See NOTES*/
#include <sys/socket.h>//函数原型
//参数//sockfd 是socket系统调用返回的服务器端socket描述符//addr 用来返回已连接的对端(客户端)的协议地址//addrlen 客户端地址长度
int accept(int sockfd,struct sockaddr *addr, socklen_t *addrlen);

        accept函数由TCP服务器调用,用于从已完成连接队列队头返回下一个已完成连接。如果已完成连接队列为空,那么进程被投入睡眠。

        该函数的返回值是一个新的套接字描述符,返回值是表示已连接的套接字描述符,而第一个参数是服务器监听套接字描述符。一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建一个已连接套接字(表示TCP三次握手已完成),当服务器完成对某个给定客户的服务时,相应的已连接套接字就会被关闭。

        

#include <sys/types.h>    /*See NOTES */
#include <sys/socket.h>//函数原型
//参数//sockfd 是目的服务器的sockect描述符//addr 是服务器端的IP地址和端口号的地址结构指针//addrlen 地址长度常被设置为sizeof(struct sockaddr)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

        connect函数用于绑定之后的client端(客户端),与服务器建立连接。

        该函数成功返回0,遇到错误时返回-1,并且error中包含相应的错误码。 


6.6 数据收发函数

        常用api

//在TCP套接字上发送数据函数:有连接//函数原型
ssize_t send(int s, const void *msg, size_t len, int flags);
//包含3要素:套接字s,待发数据msg,数据长度len
//函数只能对处于连接状态的套接字使用,参数s为已建立好连接的套接字描述符,即accept函教的返回值
//参数msg指向存放待发送数据的缓冲区
//参数len为待发送数据的长度,参数flags为控制选项,一般设置为0
//在TCP套接字上接收数据函数:有连接//函数原型
ssize_t recv(int s,void *buf,size_t len, int flags);
//包含3要素:套接字s,接收缓冲区buf,长度len
//函数recv从参数s所指定的套接字描述符(必须是面向连接的套接字)上接收数据并保存到参数buf所指定的缓冲区
//参数len则为缓冲区长度,参数flags为控制选项,一般设置为0

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

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

相关文章

定位器与PWM的LED控制

文章目录 一、STM32定时器二、脉宽调制pwm三、定时器控制led&#xff08;1&#xff09;实验内容&#xff08;2&#xff09;创建工程&#xff08;3&#xff09;Keli程序&#xff08;4&#xff09;观察波形图&#xff08;5&#xff09;实物连接图&#xff08;6&#xff09;实践效…

一文了解MyBatis

文章目录 MyBatis1. MyBatis的执行流程2. MyBatis是否支持延迟加载3. MyBatis延迟加载的底层原理4. MyBatis的二级缓存机制用过吗5. 谈谈MyBatis框架的优势6. 简单描述MyBatis的工作原理7. MyBatis中的sql标签8. MyBatis中的${}和#{}的区别9. MyBatis中ResulyMap的作用[重要]10…

UDP网络聊天室(更)

服务器端 #include <header.h> typedef struct node {char name[20];struct sockaddr_in cli_addr;struct node *next; }node,*node_p; typedef struct msg {char type;char name[20];char text[128]; }msg; node_p create_link() {node_p H(node_p)malloc(sizeof(node)…

网络业务创新驱动下的DPU P4技术,中科驭数在网络开源技术生态大会上分享最新进展

2024年5月25日&#xff0c;由中国通信学会指导&#xff0c;中国通信学会开源技术专业委员会、江苏省未来网络创新研究院主办的第四届网络开源技术生态大会在北京举办&#xff0c;中科驭数产品总监李冬以《合作如兰&#xff0c;扬扬其香 中科驭数助力P4产业发展与生态建设》为主…

Cweek2+3

C语言学习 五.操作符 5.单目操作符(2) sizeof不能用于计算动态分配的内存 在对数组使用sizeof时&#xff0c;返回的是整个数组的大小&#xff08;所有元素的总字节数&#xff09;。而对指针使用sizeof时&#xff0c;返回的是指针本身的大小&#xff08;通常是机器字长的大小…

怎么简单的把图片缩小?图片在线改大小的方法

在日常工作中经常需要在网上上传图片&#xff0c;但是一般网上不同的平台对上传的图片大小和尺寸都会有限定的要求&#xff0c;不符合要求无法正常上传使用。所以当遇到图片太大的问题时&#xff0c;该如何快速修改图片大小&#xff0c;有很多的小伙伴都很关注这个问题的解决方…

【Qt秘籍】[002]-开始你的Qt之旅-下载

一、Qt的开发工具有哪些&#xff1f; Qt的开发工具概述Qt支持多种开发工具&#xff0c;其中最常见的开发工具是 1.QtCreator 【易上手/有少量bug/适合新手】 2.VisualStudio 【功能强大/易出错/需要更多额外配置】 3.Eclipse 【清朝老兵IDE/不建议使用】 【注意&#xff1…

【第三节】类的构造和析构函数

目录 一、数据成员的初始化 二、构造函数 2.1 什么是构造函数 2.2 构造函数的注意事项 三、析构函数 四、带参数的构造函数 五、缺省构造函数 六、构造函数初始化列表 七、拷贝构造函数和调用规则 八、深拷贝和浅拷贝 九、总结 一、数据成员的初始化 定义普通变量&am…

基于BP神经网络和小波变换特征提取的烟草香型分类算法matlab仿真,分为浓香型,清香型和中间香型

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...................................................................................... …

深入探究Java自动拆箱与装箱的实现原理

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

Linux:进程控制(二.详细讲解进程程序替换)

上次讲了&#xff1a;Linux&#xff1a;进程地址空间、进程控制&#xff08;一.进程创建、进程终止、进程等待&#xff09; 文章目录 1.进程程序替换1.1概念1.2原理1.3使用一个exec 系列函数execl&#xff08;&#xff09;函数结论与细节 2.多进程时的程序替换3.其他几个exec系…

mysql连接池的实现

概要&#xff1a;本文介绍mysql连接池的实现&#xff0c;要求读者了解线程池 一、为什么需要mysql连接池&#xff1f; 资源复用 &#xff1a;不使用连接池&#xff0c;每次数据库请求都新建一条连接&#xff0c;将耗费系 统资源。 流程如下&#xff1a; 通过三次握手建立 TC…

大数据面试题 —— Hive

目录 Hive 是什么为什么要使用 HiveHive 的优缺点Hive的实现逻辑&#xff0c;为什么处理小表延迟比较高你可以说一下 HQL 转换为 MR 的任务流程吗 ***你可以说一下 hive 的元数据保存在哪里吗 ***Hive与传统数据库之间的区别Hive内部表和外部表的区别 ***hive 动态分区与静态分…

Hotcoin Research | 市场洞察:2024年5月13日-5月19日

加密货币市场表现 目前&#xff0c;加密货币总市值为1.32万亿&#xff0c;BTC占比54.41%。 本周行情呈现震荡上行的态势&#xff0c;BTC在5月15日-16日&#xff0c;有一波大的拉升&#xff0c;周末为震荡行情。BTC现价为67125美元。 上涨的主要原因&#xff1a;美国4月CPI为3…

效率工作:一键为多种资产添加统一材质(小插件)

1.需求分析&#xff1a; 当导入一批资产&#xff0c;或者有同一批结构体需要添加相同材质时&#xff0c;单独为每个模型都添加材质费时费力&#xff0c;有没有什么办法&#xff0c;能同时为多个资产添加材质。 2.操作实现 1.在网上找到了一款插件&#xff0c;经过验证&#xf…

如何将天猫内容保存为PDF格式?详细步骤与实战解析

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;保存天猫内容的重要性 二、环境准备与工具安装 1. 安装必要的Python包…

SpringCloud之SSO单点登录-基于Gateway和OAuth2的跨系统统一认证和鉴权详解

单点登录&#xff08;SSO&#xff09;是一种身份验证过程&#xff0c;允许用户通过一次登录访问多个系统。本文将深入解析单点登录的原理&#xff0c;并详细介绍如何在Spring Cloud环境中实现单点登录。通过具体的架构图和代码示例&#xff0c;我们将展示SSO的工作机制和优势&a…

HCIP-Datacom-ARST自选题库__BGP多选【22道题】

1.BGP认证可以防止非法路由器与BGP路由器建立邻居&#xff0c;BGP认证可以分为MD5认证和Keychain认证&#xff0c;请问以下哪些BGP报文会携带BCGP Keychain认证信息?(报头携带) open Update Notication Keepalive 2.传统的BGP-4只能管理IPv4单播路由信息&#xff0c;MP-B…

Spring-Cloud-OpenFeign源码解析-04-调用流程分析

在Spring-Cloud-OpenFeign源码解析-03-FeignClientFactoryBean分析到&#xff0c;通过Autowired或者Resource注入FeignClient实例的时候&#xff0c;实际上返回的是JDK动态代理对象&#xff0c;具体的实现逻辑在InvocationHandler的invoke方法中 回看ReflectiveFeign.newInsta…

AI大模型日报#0528:Greg专访 | 为什么OpenAI最先做出GPT-4、xAI获60亿美元融资、李飞飞经典对话Hinton

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE 4.0&#xff09;、“零一万物”&#xff08;Yi-34B&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xff0…