《3.linux应用编程和网络编程-第9部分-3.9.linux网络编程实践》 inet_addr inet_ntop inet_pton htons

news2024/11/26 22:23:28

3.9.1.linux网络编程框架
3.9.1.1、网络是分层的
(1)OSI  7层模型 : 理论指导,7层
(2)网络为什么要分层

    网络太复杂
(3)网络分层的具体表现

    我们只研究 APP+API
3.9.1.2、TCP/IP协议引入
(1)TCP/IP协议是用的最多的网络协议实现
(2)TCP/IP分为4层,对应OSI的7层
(3)我们编程时最关注应用层,了解传输层,网际互联层和网络接入层不用管
3.9.1.3、BS和CS
(1)CS架构介绍(client server,客户端(client ) 服务器(server)架构: QQ、迅雷、)
(2)BS架构介绍(broswer server,浏览器服务器架构 : 优酷网站(不是APP)、)

3.9.2.TCP协议的学习1
3.9.2.1、关于TCP理解的重点
(1)TCP协议工作在传输层,对上服务socket接口,对下调用IP层

        
(2)TCP协议面向连接,通信前必须先3次握手建立连接关系后才能开始通信

        QQ聊天是 非 面向连接!!
(3)TCP协议提供可靠传输,不怕丢包、乱序等。
3.9.2.2、TCP如何保证可靠传输
(1)TCP在传输有效信息前要求通信双方必须先握手,建立连接才能通信
(2)TCP的接收方收到数据包后会ack(ack回应)给发送方,若发送方未收到ack会丢包重传
(3)TCP的有效数据内容会附带校验,以防止内容在传递过程中损坏
(4)TCP会根据网络带宽来自动调节适配速率(滑动窗口技术)
(5)发送方会给各分割报文编号,接收方会校验编号,一旦顺序错误即会重传。

   多个包 发送时,每个包都有编号,保证顺序不好出错

以上不用我们实现,我们只要 知道怎么使用 就行!!!

3.9.3.TCP协议的学习2
3.9.3.1、TCP的三次握手

参考:TCP协议中的三次握手和四次挥手(图解)_三次握手和四次挥手图_whuslei的博客-CSDN博客
(1)建立连接需要三次握手
(2)建立连接的条件:服务器listen时客户端主动发起connect

写 代码时,我们不会碰到这些 细节!!!

3.9.3.2、TCP的四次握手
(3)关闭连接需要四次握手
(4)服务器或者客户端都可以主动发起关闭
注:这些握手协议已经封装在TCP协议内部,socket编程接口平时不用管
3.9.3.3、基于TCP通信的服务模式
(1)具有公网IP地址的服务器(或者使用动态IP地址映射技术)

      公网数量是有限的,你有钱也不一定能容易买到, 都是使用动态IP 地址 映射技术
(2)服务器端:3个函数 socket、bind、listen后处于监听状态
(3)客户端socket后,直接connect去发起连接。
(4)服务器收到并同意客户端接入后会建立TCP连接,然后双方开始收发数据,收发时是双向的,而且双方均可发起
(5)双方均可发起关闭连接
3.9.3.4、常见的使用了TCP协议的网络应用
(1)http 应用层协议、ftp 纯传文件
(2)QQ服务器
(3)mail服务器:邮件服务器


3.9.4.socket编程接口介绍
3.9.4.1、建立连接
(1)socket。socket函数类似于open,用来打开一个网络连接,如果成功则返回一个网络文件描述符(int类型),之后我们操作这个网络连接都通过这个网络文件描述符。
(2)bind
(3)listen
(4)connect
3.9.4.3、发送和接收
(1)send和write  :都是发送
(2)recv和read    : 都是接收
3.9.4.4、辅助性函数
(1)inet_aton、inet_addr、inet_ntoa  : IP地址转换,这三函数 不支持 IPV6
(2)inet_ntop、inet_pton  :  IP地址转换 支持 IPV6

1.socket
   #include <sys/socket.h>

       int socket(int domain, int type, int protocol);

socket 函数:打开一个网络连接,成功返回一个网络文件描述符(类似于open函数)
int domain : 域 网络套接字,表示 ipv4的网络,还是ipv6 的网络 ,AF_INET :IPV4  ;    
                                AF_INET6:       IPV6                                                   
                                                    
int type :指定类型       SOCK_STREAM :TCP网络类型;  SOCK_DGRAM :UDP网络类型;


int protocol : 协议, 0表示默认协议,

返回值 -1 是错误;

2. bind 读邦德
 #include <sys/socket.h>

       int bind(int socket, const struct sockaddr *address,
              socklen_t address_len);

bind 函数:把本地的IP地址 和 socket(就是socket函数返回的网络文件描述符) 绑定起来 ,

int socket: socket 函数成功返回一个网络文件描述符(类似于open函数)
const struct sockaddr *address : 输入型参数
                   struct sockaddr,这个结构体是网络编程接口中用来表示一个IP地址的,注意这个IP        
                   地址是不区分IPv4和IPv6的(或者说是兼容IPv4和IPv6的)
socklen_t address_len : 长度

返回值 : 正确返回 0;

3. listen 读雷深 ,监听
#include <sys/socket.h>

       int listen(int socket, int backlog);

int socket :socket 函数成功返回一个网络文件描述符(类似于open函数)

int backlog : 表示可以同时 监听几个(监听队列),队列得有一个长度,设置监听队列的 长度!

返回值 : 正确返回 0;

3.1   accept  阻塞等待 客服端来连接服务器
   #include <sys/socket.h>

       int accept(int socket, struct sockaddr *restrict address,
              socklen_t *restrict address_len);


4.服务器 经过 socket 、bind 、listen ; 客户端先调用socket 就可以 来进行 连接 connect

connect 读 壳耐克特

   #include <sys/socket.h>

       int connect(int socket, const struct sockaddr *address,
              socklen_t address_len);

int socket : socket 函数成功返回一个网络文件描述符(类似于open函数)
const struct sockaddr *address :连接的 服务器 IP 地址
socklen_t address_len :
返回值 : 正确返回 0;

5.  发送数据 write
  #include <unistd.h>

      
       ssize_t write(int fildes, const void *buf, size_t nbyte);

int fildes : open函数返回的 文件描述符( socket 函数成功返回一个网络文件描述符)
const void *buf : 数据 buf
size_t nbyte :数据 长度


6. 发送数据 send 
 #include <sys/socket.h>

       ssize_t send(int socket, const void *buffer, size_t length, int flags);

int flags :如果 flags 是 0 ,就和 write 一样!
             MSG_EOR : 发一个结尾,信息的结尾(特殊协议)
             MSG_OOB : 带外数据(特殊协议)
正常通讯 用不到 flags


7. 辅助性函数  : IP 地址 转换

7.1  inet_ntop :n 网络(32位2进制), p 字符串 点分十进制

   #include <arpa/inet.h>

       const char *inet_ntop(int af, const void *src,
                             char *dst, socklen_t size);





7.2   inet_addr

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>



in_addr_t inet_addr(const char *cp);
const char *cp :  字符串 点分十进制
in_addr_t : 返回一个 typedef uint32_t in_addr_t;		网络内部用来表示IP地址的类型




7.3 inet_pton


 #include <arpa/inet.h>

 int inet_pton(int af, const char *src, void *dst);

int af : 网络IPV4 还是 IPV6 。 AF_INET :IPV4  ;    AF_INET6:   IPV6

const char *src :字符串  点分 十进制 的 IP 地址 

void *dst : 输出型参数 。如果是  IPV4 :struct in_addr  ; 如果是 IPV6:  struct in6_addr

inet_pton 函数 如果正确 返回1。


7.4 inet_ntop

#include <arpa/inet.h>

 const char *inet_ntop(int af, const void *src,
                             char *dst, socklen_t size);

int af : 网络IPV4 还是 IPV6 。 AF_INET :IPV4  ;    AF_INET6:   IPV6



8  端口号 解决 大小端 模式

 #include <arpa/inet.h>

       uint32_t htonl(uint32_t hostlong); 当前电脑 字节序 转成 网络 字节序 32位

       uint16_t htons(uint16_t hostshort); 当前电脑 字节序 转成 网络 字节序 16位

       uint32_t ntohl(uint32_t netlong);

       uint16_t ntohs(uint16_t netshort);

h : host 主机
to : 转到
n  : net 网络
l  : long  4 个字节
(3)typedef uint32_t in_addr_t;		网络内部用来表示IP地址的类型
(4)struct in_addr
  {
    in_addr_t s_addr;
  };
(5)struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;                 /* Port number.  */
    struct in_addr sin_addr;            /* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
                           __SOCKADDR_COMMON_SIZE -
                           sizeof (in_port_t) -
                           sizeof (struct in_addr)];
  };
(6)struct sockaddr			这个结构体是linux的网络编程接口中用来表示IP地址的标准结构体,bind、connect等函数中都需要这个结构体,这个结构体是兼容IPV4和IPV6的。在实际编程中这个结构体会被一个struct sockaddr_in或者一个struct sockaddr_in6所填充。

示例1  inet_addr 函数 点分十进制  IP 地址 转成  十六进制的 IP  地址

网络字节序: 其实就是 大端模式,不允许 小端模式

代码:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>



#define IPADDR "192.168.1.102"/* 字符串 点分十进制 的IP 地址 */


int main(void)
{
	
	in_addr_t addr = 0; /* typedef uint32_t in_addr_t;		网络内部用来表示IP地址的类型 */
	
	/* 字符串 点分十进制 的IP 地址 转成  uint32_t 类型的 IP 地址 */
	addr = inet_addr(IPADDR);  /* inet_addr函数返回   uint32_t 类型的 IP 地址 */
	
	printf("addr = 0x%x \n",addr);
	
	return 0;
}



运行结果:

 示例2  inet_pton 函数 :点分十进制  IP 地址 转成  十六进制的 IP  地址

代码:

#include <stdio.h>

#include <arpa/inet.h>



#define IPADDR "192.168.1.102"/* 字符串 点分十进制 的IP 地址 */


int main(void)
{
	int ret = 0; /* 定义 inet_pton 返回值  */
	
	struct in_addr addr = {0};/* 定义 inet_pton 函数的 第三个参数  */
	
	/* 字符串 点分十进制 的IP 地址 转成  uint32_t 类型的 IP 地址 */
	ret = inet_pton(AF_INET, IPADDR, &addr);  /*  */
	
	if(ret!= 1)
	{
		printf("inet_pton error \n");
		return -1;
	}
	
	printf("addr.s_addr = 0x%x \n",addr.s_addr);
	
	return 0;
}

/*************************

addr.s_addr 是从哪里来的???

答:
typedef uint32_t in_addr_t;		网络内部用来表示IP地址的类型
struct in_addr
{
   in_addr_t s_addr;
};

*************************/

运行结果:

 示例3   inet_ntop 函数 :十六进制的 IP  地址  转成   点分十进制  IP 地址

#include <stdio.h>
#include <arpa/inet.h>



int main(void)
{
	const char* ret = NULL ; /* 定义 返回值 ,当一个函数的 返回值 是cost时, 我们定义的 返回值也要加 const  */
	char buf[50]= {0};
	struct in_addr addr = {0};/*   */
	addr.s_addr = 0x6601a8c0 ;/* 定义 uint32_t 类型的 IP 地址   */

	
	/* 把 uint32_t 类型的 IP 地址 转成  字符串 点分十进制 的IP 地址   */
	ret = inet_ntop(AF_INET,&addr,buf,sizeof(buf));  /*  */
	
	if(ret == NULL)
	{
		printf("inet_ntop error \n");
		return -1;
	}
	
	printf("buf = %s \n",buf);
	
	return 0;
}

/*************************

addr.s_addr 是从哪里来的???

答:
typedef uint32_t in_addr_t;		网络内部用来表示IP地址的类型
struct in_addr
{
   in_addr_t s_addr;
};

*************************/

运行结果:

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

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

相关文章

浙大数据结构第三周之03-树1 树的同构

题目详情&#xff1a; 给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2&#xff0c;则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的&#xff0c;因为我们把其中一棵树的结点A、B、G的左右孩子互换后&#xff0c;就得到另外一棵树。而图2就不是同构的…

Python物联网开发-Python_Socket通信开发-Python与Tcp协议物联网设备通信-Socket客户端

一、前言 Python在物联网开发中的重要愈来愈重&#xff0c;因此&#xff0c;掌握Python语言与物联网设备之间的通信就显得尤为重要&#xff0c;可以通过编写Python程序实现获取物联网设备的传感器数值并可以更改物联网设备上的执行器状态。 二、程序实现 首先&#xff0c;当使…

中位数(树状数组+二分)

L-中位数_2023河南萌新联赛第&#xff08;一&#xff09;场&#xff1a;河南农业大学 (nowcoder.com) 树状数组二分 #include <bits/stdc.h> using namespace std; typedef long long ll; const int N2e6; const long long inf 0x7f7f7f7f7f7f7f7f; #define endl \n in…

【Android Framework系列】第5章 AMS启动流程

1 AMS简介 AMS&#xff08;Activity Manager Service&#xff09;是Android中最核心的服务&#xff0c;管理着四大组件的启动、切换、调度及应用进程的管理和调度等工作。AndroidQ将Activity移到了ActivityTaskManagerService中&#xff0c;但也和AMS相关联。 AMS通过使用一些…

【来不及刷题之】44、滑动窗口最小值

暴力方法&#xff1a;超时 class Solution {public int[] maxSlidingWindow(int[] nums, int k) {int nnums.length;int sizen-(k-1);int[] resnew int[size];int slow0,quickk-1;int maxNumfindMax(nums,slow,quick);res[0]maxNum;while (quick<n-1){quick;int addNumnums…

66. 两个链表的第一个公共结点

目录 链接&#xff1a; 题目&#xff1a; 思路&#xff1a; 代码&#xff1a; 图片&#xff1a; 链接&#xff1a; 原题链接 题目&#xff1a; 输入两个链表&#xff0c;找出它们的第一个公共结点。 当不存在公共节点时&#xff0c;返回空节点。 数据范围 链表长度 [1,200…

mapbox跳过accesstoken检测

不写token的时候&#xff0c;控制台就会报这个错 写上token的时候&#xff0c;就会报这个错 然后想让这个错不再出现&#xff0c;就不要再声明mapboxgl.accessToken&#xff0c;并且把node_mudules这个文件夹下面的这个文件里面的红圈内的括号内容改成false。 this._request…

React 安装 报错“Modal不能用作jsx组件”

提示 &#xff1a;‘Modal’ cannot be used as a JSX component. 原因&#xff1a;可能导致是类似antd组件报错 要确认react ts 版本是否适配 解决方法&#xff1a; 第一步&#xff1a;查看代码中的 package.json 文件 查看 typescript 与 types/react 第二步&#xff1a;查…

这些ai图片处理工具就是你神奇的创作伙伴

当我们需要图像来代表某种概念或主题时&#xff0c;我们通常需要花费大量的时间去寻找、编辑、或者设计一张符合要求的图片。但是现在&#xff0c;随着人工智能技术的发展&#xff0c;越来越多的ai自动生成图片软件被开发出来&#xff0c;让我们可以更快捷地获取所需的图像。那…

【Flutter】 Flutter 实现 List Sort 排序 解决复杂业务逻辑下的数据排序问题

文章目录 一、前言二、Flutter 中的 List 排序基础1. Flutter 中的 List 简介2. List 的基本排序方法3. 自定义排序规则 三、在 Flutter 中实现复杂业务逻辑的 List 排序1. 业务逻辑一&#xff1a;根据对象属性排序2. 业务逻辑二&#xff1a;多条件排序 四、完整的 Flutter Lis…

pythonocc进阶学习:faces的inner wire与outer wire

总目录 >> PythonOCC入门进阶到实战(目前已更新入门篇、基础篇和进阶篇) 我们在这篇文章中绘制了带有holes的面&#xff0c; 本篇是在读取到外部文件如brep&#xff0c;igs&#xff0c;stp后获取面的性质&#xff0c;寻找面中的wires的正向与逆向 只显示外wire from O…

TCP/IP参考模型之http协议分层,三次握手、四次挥手

三次握手和四次挥手的过程&#xff1a; 三次握手&#xff1a; TCP建立连接的过程我们称之为3次握手。 &#xff08;1&#xff09;第一次握手 PC1使用一个随机的端口号向PC2的80端口发送连接请求&#xff0c;此过程的典型标志为SYN控制位为1&#xff0c;其他五位为0。 &#x…

credal set 的一些熵

今天看论文的时候看到credal set 的upper entropy [1]&#xff0c;另外作者还给出了一些这个熵的优点。 当然在[2] 里面又变成了缺点。 注意在上一篇博文&#xff0c;credal decision tree的论文里面&#xff0c;作者又推翻了自己的观点&#xff0c;认为这个熵是disaggregat…

C++数据结构笔记(9)树与二叉树的基本概念

1.只有一个结点也可以称为树&#xff0c;只不过没有叶子结点&#xff1b;也可以有0个结点&#xff0c;称为空树。 2.树具有递归性&#xff0c;树中还有树 3.结点的度&#xff1a;结点所拥有的子树的个数 4.树的高度&#xff1a;树的子树的最高层数 5.树的广义表示法&#x…

多肽合成定制756500-22-8,cyclo(Arg-Gly-Asp-d-Phe-Glu),试剂信息说明

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ 英文名称&#xff1a;cyclo(Arg-Gly-Asp-d-Phe-Glu) 规格标准&#xff1a;1g、5g、10g CAS&#xff1a;756500-22-8 分子式&#xff1a;C26H36N8O9 分子量&#xff1a;604.61 ------cyclo(Arg-Gly-Asp-d-Phe-Glu)结构式-…

AuthenticationFailedException: 526 Authentication failure[0]的解决方案

0、一句话概括bug的原因 项目更换了邮箱服务器&#xff0c;原服务器支持的账号格式在新服务器上不被支持&#xff1b;即发送给新服务器的账号错误。 1、概述 &#xff08;1&#xff09;bug: java程序通知阿里云邮箱服务器发送邮件失败。 异常报错信息&#xff1a;Authentic…

如何在 Blender 中更快地渲染?这些技巧需要知道

Blender 是一款开源 3D 建模和动画软件&#xff0c;动画艺术家、产品设计师和游戏创作者经常使用。Blender 不仅允许用户创建 2D 对象或角色并对其进行动画处理以获得 3D 模型&#xff0c;而且 Blender 背后还有强大的艺术家和计算机科学家社区&#xff0c;不断改进代码以提供功…

基于javascript的可以自定义设置圆几等份的抽奖示例

基于javascript的可以自定义设置圆几等份的抽奖示例 效果示例图代码示例使用class 效果示例图 代码示例 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style type"text/css">* {padding…

声音合成——Foley Sound——DECASE项目——多模态智能感知与应用——论文复现(4)

文章目录 下载对应的代码attributeerror: adam object has no attribute get_updatesNameError: name _calculate_reconstruction_loss is not defined 下载对应的代码 论文下载链接安装tensorflow环境&#xff0c;这里需要一些前奏&#xff0c;比如说如何安装cuda&#xff0c…