IP地址是在IP协议中用来标识网络中不同主机的地址。
IP协议有两个版本,IPv4和IPv6。
IPv4:网际协议版本4(英语:Internet Protocol version 4,IPv4),又称互联网通信协议第四版,是网际协议开发过程中的第四个修订版本,也是此协议第一个被广泛部署的版本。IPv4是互联网的核心,也是使用最广泛的网际协议版本,其后继版本为IPv6,直到2011年,IANA IPv4位址完全用尽时,IPv6仍处在部署的初期。(抄自维基百科)
IPv4使用32位空间来存储地址,是一个32位的整数,我们通常使用点分十进制来表示这个IP地址,用点分割每一个字节,每一个字节的范围是0~255。
IPv6:网际协议第6版(英文:Internet Protocol version 6,缩写:IPv6)是网际协议(IP)的最新版本,用作互联网的网上层协议,用它来取代IPv4主要是为了解决IPv4地址枯竭问题,不过它也在其他很多方面对IPv4有所改进。IPv6的设计目的是取代IPv4,然而长期以来IPv4在互联网流量中仍占据主要地位,IPv6的使用增长缓慢。在2017年7月,通过IPv6使用Google服务的用户百分率首次超过20%。
IPv6使用128位地址来解决IPv4的地址枯竭问题,增加的地址数为2的128次,但是由于其不向下兼容IPv4,所以导致软件厂商不愿意用,没有推广起来(要知道IPv6在1994年就被提出,1998年就已经被定为草案的标准了)。
源IP地址和目标IP地址可以理解为唐僧去西天取经,每次到一个地方,唐僧都会说:“贫僧从东土大唐而来,到西天求取真经的。”
在数据包头部中有两个IP地址,分别叫源IP地址和目标IP地址,表明了自己从哪儿来到哪儿去。
但是光有源IP和目标IP地址显然无法将信息准确传达,只能找到需要接收信息的电脑,可是电脑上有很多软件,电脑怎么得知传消息给哪个软件?这里使用的是另一个概念——端口。
端口号(port)是传输层协议的内容
区分端口号和进程ID
一个端口号只能绑定一个进程,但是一个进程可以绑定多个端口号。
就好比我们打电话给移动客服,打的都是10086,但是我们现在打和等会打,接待的移动客服的工号是不一样的。
传输层协议(TCP和UDP)的数据段中有两个端口号,分别叫源端口号和目标端口号,就是在描述“数据段是谁发的,要发给谁”
传输控制协议(英语:Transmission Control Protocol,缩写为TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能。
用户数据报协议(英语:User Datagram Protocol,缩写为UDP),又称用户数据报文协议,是一个简单的面向数据报的传输层协议,正式规范为RFC 768。
在TCP/IP模型中,UDP为网络层以上和应用层以下提供了一个简单的接口。UDP只提供数据的不可靠传递,它一旦把应用程序发给网络层的数据发送出去,就不保留数据备份(所以UDP有时候也被认为是不可靠的数据报协议)。
TCP数据传输速度慢于UDP,但是可以保证数据的安全传输,用于对数据安全性要求较高的场景,牺牲了传输性能但是数据能保证安全。
UDP传输速率快,实时性高,常用于传输音乐、视频,对数据完整性要求不高的,对实时要求高的场景。
但是从我查阅的资料看,据说各大网站用的都是HTTP协议,而HTTP协议是基于TCP的,所以如果说音乐和视频用TCP传好像也没有什么毛病,至于直播,尽管说是说更好或者应该用UDP,但是好像都用的TCP。
内存中存储数据有大端小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网络数据流同样有大端小端之分,如何定义网络数据流的地址?
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
socket是一套接口,用于网络编程,同时也是一个结构体,想要开始网络编程,就需要创建一个套接字(socket),创建成功后才可对套接字操作,完成网络上的数据传输。
//你可能在别的地方比如百度百科看到不一样的参数命名,我所列函数均为从man手册查询的
int socket(int domain, int type, int protocol);
//创建套接字
// domain 协议族,可以选择IPv4、IPv6或者UNIX
// 各个协议族对应参数IPv4->AF_INET IPv6->AF_INET6 UNIX->AF_UNIX
// tyoe 传输数据方式,数据流(SOCK_STREAM)还是数据报(SOCK_DGRAM)或是其他方式
// protocol 指定协议 TCP->IPPROTO_TCP UDP->IPPROTO_UDP
//返回值:成功返回套接字描述符,错误返回-1
int bind(SOCKET socket, const struct sockaddr* address, socklen_t address_len);
//绑定地址
// socket 套接字描述符
// address 是一个sockaddr结构指针,该结构中包含了要结合的地址和端口号
// address_len 缓冲区长度
//返回值:成功返回0,否则为SOCKET_ERROR
int listen(int sockfd, int backlog);
//监听
// sockfd 一个已绑定未被连接的套接字描述符
// backlog 连接请求队列,一般2-4,5也不是不可以
//返回值:成功返回0,失败返回SOCKET ERROR
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
//接收连接队列第一个连接请求
// fd 套接字描述符
// addr 套接字结构体指针
// addrlen 结构体大小
//返回值:成功返回一个新的套接字描述符,失败返回-1
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
//接收信息
// socket 已连接的对方的套接字描述符
// buf 用于接收数据的缓冲区
// len 缓冲区长度
// flags 指定调用方式
//返回值:成功返回读入的字节数,如果连接已中止,返回0,错误返回SOCKET_ERROR
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
//发送信息
// sockfd 已连接的对方的套接字描述符
// buf 发送内容的字符串首地址
// len 发送长度
// flags 发送方式,一般为0
//返回值:成功返回发送的字符串长度,失败返回-1
socket是一套网络编程接口,适用各种底层的网络协议,比如IPv4和IPv6,以及UNIX Domain Socket,但是各种网络协议的地址格式并不相同。
所以接口中使用sockaddr*作为参数,这样在sockaddr结构体传入后,可以通过判断16位地址类型来判断是哪种网络协议,再对其进行操作,具有强兼容性,方便了接口使用者。