0
点赞
收藏
分享

微信扫一扫

MYSQL:删除指定时间范围内每个电站每天发电数据除最大值以外的记录

禾木瞎写 2024-09-04 阅读 17

目录

一,认识端口号

1.1 背景

1.2 端口号是什么

1.3 三个问题

二,认识Tcp协议和Udp协议

三,网络字节序

四,socket编程接口

4.1 socket常见API

4.2 sockaddr结构


一,认识端口号

1.1 背景

  •  网络协议的下三层:网络层,传输层,数据链路层,主要解决数据安全可靠地被送到远端机器
  • 用户使用应用层软件,完成数据地发送和接收,而软件要进行通信就要先启动起来,而启动一个软件也就是进程创建
  • 所以日常我们网络通信的本质:就是“进程间通信”,两个进程间要通信就是让两个进程看到同一份资源,这个资源就是网络,而这个网络再具体一点就是网络协议栈

1.2 端口号是什么

端口号:是传输层协议的内容,是一个2字节16位的整数,就是4个数字,它用来标识一个进程,告诉操作系统,当前这个数据从传输层要交给应用层的哪一个应用

  • 端口号无论对于客户端还是服务器,都能唯一地标识该主机上的一个网络应用层的进程,这点类似于进程的PID,一个端口号只能被一个进程占用
  • 在公网上,ip地址能表示唯一的一台主机,端口号(port),用来标识该主机上的唯一一个进程,所以 ip + port = 标识全网唯一的一个进程
  • 所以客户端和服务器都要有自己的ip和port,这种基于ip + port 的通信方式,我们叫做socket,后面会讲

1.3 三个问题

二,认识Tcp协议和Udp协议

网络协议栈是贯穿整个体系结构的,在操作系统层,应用层和驱动层都有自己的协议。而离我们普通程序员最近的就是使用系统调用接口实现网络通信了,所以离我们最近的就是传输层,传输层应用最广泛最受欢迎的两种协议就是TCP协议UDP协议

Tcp:传输控制协议(Transmission Control Protocol),是一种面向连接的,可靠的,基于字节流的传输层协议。

  • 如果两台主机想通过Tcp进行数据通信,那么必须先建立好连接道路,并确保建立成功后才进行数据传输
  • 同时,Tcp协议也是保证数据传输可靠的协议,数据在传输过程中如果出现了丢包,乱序等情况,Tcp协议都有对应的解决方法,具体我们后面再讲

 UDP:用户数据报协议(User Datagram Protocol),是一种无需建立连接,不可靠的,面向数据报的传输层协议

  • 如果两台主机要使用Udp通信,无需建立连接,一方根据IP和端口直接就将数据发送给对方,这也就意味着Udp协议是不可靠的,中途出现丢包,乱序等情况,Udp都不会去处理

三,网络字节序

如果编写的程序只在本地机器上运行,那么是不需要考虑大小端转换的问题的;但是到了网络通信时,是两台主机在进行进程间通信了,那么这两台主机采用的存储方式可能不一样,比如大端机器传数据给小端机器,那么小端机器解析出来的数据就和大端机器是不一样的

所以我们解决上面的问题,为此:TCP/IP 协议 规定,网络数据流都要采用大端字节序:

注意:所有的大小端的转化工作由操作系统来完成,因为该操作属于通信细节,不过也有部分的数据需要我们自行进行处理,比如IP的端口号

同时,为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换:

#include<arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntonl(uint32_t netlong);
uint16_t ntons(uint16_t netshort);

四,socket编程接口

4.1 socket常见API

我们会后面写代码常用到的,一共是五个:

// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
 int socket(int domain, int type, int protocol);

 // 绑定端口号 (TCP/UDP, 服务器)      
int bind(int socket, const struct sockaddr *address, socklen_t address_len);

 // 开始监听socket (TCP, 服务器)
 int listen(int socket, int backlog);

 // 接收请求 (TCP, 服务器)
 int accept(int socket, struct sockaddr* address, socklen_t* address_len);

 // 建立连接 (TCP, 客户端)
 int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

4.2 sockaddr结构

可以发现,上面的每个接口的参数都有一个结构体指针 struct sockaddr* addr,下面详细介绍一下:

 套接字种类不同,就有不同的应用场景,但是网络接口的设计者不想搞三套,计划将网络接口统一抽象化;而网络接口要想统一,那么接口的参数类型必须一致,所以就设计了sockaddr这个结构体:

  • 之后在传参数的时候只要传sockaddr这一个就可以了,在设置参数之前就可以往这个结构体添加字段,这点下一篇简单Udp和程序的代码中会具体表现
  • 如上图,在调用socket API 的那些接口时,这些API就可以提取 sockaddr 内部的头16字节进行识别,进而得出我们是要进行网络通信还是本地通信,执行对应的操作,完成接口的统一
  • 注意:实际在进行网络通信时,定义的还是 sockaddr_in 这样的结构体,只是在传参的时候将该结构体的地址类型强制转换位 sockaddr* 罢了 
举报

相关推荐

0 条评论