网络基础-IP和端口号以及认识传输层协议

news/2024/11/19 19:23:41/

概念回顾

MAC地址仅需要在同一个局域网下唯一,就可以保证不会出现通讯问题。

通信的目的是两台机器上的应用软件要通信。即客户端进程和服务端进程要获取这个数据,借助主机来完成通信。故将数据在主机间转发仅仅是手段,机器收到后,需要将数据交付给指定的进程!(即两台机器通信是为了完成进程间通信)。主机如何将数据交给指定进程呢?通过端口号(标定主机上唯一的网络进程)!端口号是传输层协议的内容

IP和端口号标识公网唯一进程

源IP和目的IP

在IP数据包头部中,有两个IP地址,分别叫做源IP地址目的IP地址。但是我们光有IP地址还不可以完成通信,还需要有一个其他的标识来区分出–端口号。

端口号

端口号是一个2字节16位的整数;端口号用来标识唯一一个公网内的进程能告诉操作系统当前的这个数据要交给哪一个进程来处理

IP地址 + 端口号能够标识全网内的某一台主机的某一个进程

一个端口号只能被一个进程占用。一个进程可以绑定多个端口号,但是一个端口号只能被一个进程绑定。

传输层协议(TCP和UDP)的数据段中有两个端口号,分别叫做源端口号和目的端口号,就是在描述 “数据是谁发的, 要发给谁”

任何一个发出的报文必须有源/目标IP和源/目标port,用于找到指定主机和该主机上的唯一进程。

IP+port==>套接字。故网络通信也称为socket套接字编程。socket API是一层抽象的网络编程接口。

pid和端口号的区别和联系

pid+端口号可以标识同一台主机里进程的唯一性。进程pid和端口号分开设计是为了实现解耦,再者不是所有的进程都要进行网络通信,只有网络进程需要端口号。

传输层协议

TCP协议-安全

Transmission Control Protocol 传输控制协议

特点:有连接;可靠传输;面向字节流。可靠是需要大量数据编码处理和技术支持的。

UDP协议-简单

User Datagram Protocol 用户数据报协议

特点:无连接;不可靠传输;面向数据报。可以容忍数据丢包的场景采用UDP,简单方便使用。

网络字节序

小端:高地址存放高位。

多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网络数据流同样有大端小端之分。发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存。

因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。

不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接收数据。如果当前发送主机是小端,就需要先将数据转成大端;否则就忽略, 直接发送即可。

网络字节序和主机字节序的转换函数

#include <arpa/inet.h>
//将主机字节序转网络字节序
uint32_t htonl(uint32_t hostlong);//host to newwork long uint16_t htons(uint16_t hostshort);
//将网络字节序转成主机字节序
uint32_t ntohl(uint32_t netlong);uint16_t ntohs(uint16_t netshort);

网络编程

网络套接字接口标准是基于POSIX标准的。常见的套接字有域间socket(本主机内的进程间通信方式,struct sockeraddr_un)、原始socket(用于各种编写网络工具,允许数据传输跳过传输层/网络层)、网络socket(struct sockeraddr_in)。

虽然套接字编程有以上3种不同的应用场景,但是在系统中只设计了一套接口。网络socket的地址格式是struct sockeraddr_in,域间socket的地址格式是struct sockeraddr_un,但是在这套网络编程的接口参数中,只接收struct socketaddr这个格式,底层是系统帮我们做了转换【先读取前2个字节,如果地址类型是AF_INET就转换成sockeraddr_in,地址类型是AF_UNIX就转换成sockeraddr_un】。

通用类型的套接字结构,就是struct socketaddr。【有点像void*的作用】

在这里插入图片描述

socket常见接口

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
// 开始监听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);

两个结构

sockaddr结构

为了网络套接字和域间套接字共同使用,相当于一个基类。

struct sockaddr {sa_family_t sa_family; //通过判断16位地址类型AF_INET->使用网络套接字,AF_UNIX->使用域间套接字char        sa_data[14];//14字节,包含套接字中的目标地址和端口信息
}

虽然socket api常见接口里的参数之一是sockaddr*,但我们真正在基于IPv4编程时,使用的数据结构是sockaddr_in; 这个结构里主要有三部分信息:地址类型,端口号,IP地址

sockaddr_in结构

struct sockaddr_in {short            sin_family;    // 2 字节 ,地址族,e.g. AF_INET, AF_INET6unsigned short   sin_port;      // 2 字节 ,16位TCP/UDP 端口号 e.g. htons(3490),struct in_addr   sin_addr;      // 4 字节 ,32位IP地址char             sin_zero[8];   // 8 字节 ,不使用
};

in_addr用来表示一个IPv4的IP地址,其实就是一个32位的整数。

typedef uint32_t in_addr_t;
struct in_addr{int_addr_t s_addr;
}

人: “192.168.1.3” 方便看和理解的是点分十进制字符串风格的IP地址,每个区域的取值是[0,255]即一个字节,故IP地址是4字节,32位。对于系统来说,网络只需要4字节来表示IP就足够了。

故我们还需要进行转换(点分十进制 <–> 4字节)。

联系和区别

二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。

IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型,16
位端口号和32位IP地址。IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6。只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容。

socket API可以都用struct sockaddr *类型表示,在使用的时候需要强制转化成sockaddr_in; 这样的好
处是程序的通用性,可以接收IPv4,IPv6,以及UNIX Domain Socket各种类型的sockaddr结构体指针做为
参数。

2、虽然sockaddr和sockaddr_in包含的数据都是一样的,但他们在使用上有区别:

程序员不应操作sockaddr,sockaddr是给操作系统用的;程序员应使用sockaddr_in来表示地址,sockaddr_in区分了地址和端口,使用更方便。

一般的用法为:

程序员把类型、ip地址、端口填充sockaddr_in结构体,然后强制转换成sockaddr,作为参数传递给系统调用函数。


http://www.ppmy.cn/news/50982.html

相关文章

浅谈拉格朗日插值法

浅谈拉格朗日插值法 好像FFT要用到&#xff0c;所以就学习一手 文章目录 浅谈拉格朗日插值法什么是插值拉格朗日插值法 什么是插值 在离散数据的基础上补插连续的函数&#xff0c;使得这条连续函数经过所有离散数据点&#xff0c;这个过程就叫插值。其意义在于&#xff1a; …

Docker 部署 MySQL 一主多从

主从复制的原理&#xff1a; 1、主库&#xff1a; 创建一个有权访问binlog日志的从库账号&#xff0c;配置需要主从复制的库 有写操作时&#xff0c;可以将写操作或者写操作之后的数据记录到日志文件中(binlog) 通过一个线程通知需要同步数据…

C语言-malloc、free、memset、realloc、strcpy

malloc()开辟指定内存空间 函数原型 void *malloc(size_t size) C 库函数 void *malloc(size_t size) 分配所需的内存空间&#xff0c;并返回一个指向它的指针。 free 释放内存空间 free C 库函数 void free(void *ptr) 释放之前调用 calloc、malloc 或 realloc 所分配的…

经典文献阅读之--VGICP(体素化的ICP匹配)

0. 简介 之前我们在以前的文章中介绍了很多有关于点云匹配相关的知识&#xff0c;最近两年处理GICP这一大一统的ICP匹配方法以外&#xff0c;还有一个工作对体素化和ICP这两者打起了心思&#xff0c;《Voxelized GICP for Fast and Accurate 3D Point Cloud Registration》提出…

并查集解决图的连通性问题

并查集 1. 定义2.并查集3.模板代码4. 力扣例题4.1 剑指 Offer II 118. 多余的边4.2 力扣695. 岛屿的最大面积 1. 定义 在计算机科学中&#xff0c;并查集&#xff08;英文&#xff1a;Disjoint-set data structure&#xff0c;直译为不交集数据结构&#xff09;是一种数据结构&…

奇舞周刊第490期:WebAssembly 多语言/宿主环境中的使用

记得点击文章末尾的“ 阅读原文 ”查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞精选 ■ ■ ■ WebAssembly 多语言/宿主环境中的使用 WebAssembly (WASM) 的一个优势就是能够支持将不同语言编译成 WASM 代码&#xff0c;然后在不同的宿主环境中运行。这样就可以在不同的宿主环…

制造型企业为何需要MES管理系统,企业怎样选择合适的MES

MES管理系统是专门针对制造型企业而设计的&#xff0c;能实现对生产车间、工厂信息化管理&#xff0c;帮助制造型企业提高生产效率&#xff0c;加快数字化转型。目前针对制造型企业生产效率、企业竞争力和生产管理状况的需求&#xff0c;MES管理系统已经成为实现生产经营目标的…

商品页面翻页功能--购物车拓展

之前我们在mvc练习中曾经写过翻页功能&#xff0c;现在我们给购物车产品显示界面也加一个 1、把productlist中dao的sql语句做出修改&#xff0c;并传递需要用到的参数 再来一个返回product总数的方法 2、 对productlist的servlet拓展相关操作&#xff0c;准备好翻页的功能 3、…