前:
IP地址分为(报头包含):
源IP地址:标识网络通信发起方
目的IP地址:标识网络通信的接收方
MAC地址:标识进程当前位置
端口号port(新):标识进程唯一性(表明是哪个进程需要通信 socket会关联到对应进程)
网络通信本质:两台主机的进程间通信 两个进程间实现通信 必须各自有各自的套接字
端口号概念:
1.是一个2字节无符号16位的整数(用于表示主机上的网络通信socket)
因此最大端口号是65535(从0开始)
2.用来标识一个进程 告诉操作系统要把数据交给哪一个进程
3.一个端口号只能被一个进程占用
注意:
一个进程当中对于端口的绑定是和socket强相关 理论上该进程如果创建多个socket,可以给每一个
socket都进行绑定一个端口 则一个进程绑定多个端口
socket(套接字) : IP地址 + 端口号port
----------------
补充:
Linux下一切皆文件 网络也是一个文件 也有文件特性 虽然pid也能标识进程唯一性 但他被用于系统
1.不是所有的进程都需要port 但是所有的进程都需要pid
2.系统一个标识符(pid) 网络一个标识符(port)二者互不干扰
3.服务器重启会导致pid改变 而具有port的进程PCB会被维护在某个哈希表里 可以通过key(port)来找到对应进程
客户端的端口推荐是不主动绑定策略,这样可以尽可能的避免端口冲突,让系统选择合适端口绑定,因此不固定
服务端的端口必须是固定的,因为总是客户端先请求服务端,因此必须提前获知服务端地址端口信息
但是一旦服务器端端口改变,会造成之前的客户端的信息失效找不到服务端了
----------------
小端:低字节位数据存放在内存低地址处, 高字节位数据存放在内存高地址处
大端:高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址
网络字节序为大端字节序
小端机在网络中发送数据时会转成大端 接收数据时再转成小端
对应函数接口:
#include <arpa/inet.h>
// 主机序列转网络序列
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
// 网络序列转主机序列
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
函数名称解析:
n 对应是 network(网络)h 对应是 host(主机)s 对应是 short(16位)l 对应是 long(32位)
TCP协议:
传输控制协议
需要通信双方建立连接
是一种可靠传输,不会发生丢包等问题
面向字节流
UDP协议:
用户数据报协议
不需要通信双方建立连接,直接发生即可
不可靠传输,可能会发生丢包等问题
描写数据报
二者都是传输层协议 只是两种不同的方式 先有个概念粗略理解下
----------------
HTTP协议是应用层协议 在传输层基于TCP协议实现(可靠是TCP提供的 TCP提供字节流传输)
IP协议是网络层协议 TCP和UDP协议在网络层都是基于IP协议的(实现数据报传输)
---------------
中:
socket:
对 TCP / IP协议进行封装 编程调用接口 描述IP地址和端口,是一个通信链的句柄
可以基于TCP 面向连接 也可以基于UDP无连接
int socket(int domain, int type, protocol)
第一个参数:
表示网络通信还是本地通信 经常使用的是AF_INET
表示使用IPv4
的网络套接字进行网络通信
第二个参数:
表示面向字节流(sock_steram(tcp))还是面向用户数据报(sock_dgram(udp))
第三个参数:
表明用什么协议 一般第二个参数就把协议定下来了 所以一般是0
返回值:
返回文件描述符 失败返回-1
bind:
将IP地址和端口号port和系统绑定
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
1.绑定上个函数返回的文件描述符
2.存放了服务端用于通信的地址和端口的结构体
3.addr结构大小
4.成功返回0 失败返回-1
套接字类型:
网络套接字:用户跨主机之间的通信 也能支持本地通信
原始套接字:可以跨过传输层(TCP/UDP)访问底层的数据
域间套接字:只能在本地通信
后:
这里打算实现UDP/TCP网络通信 我先把理论都写完再实现
想提前学习的xd可以先看下这个大佬的文章 挺细致的
先更新到这了xdm 打算换种复习方式 其他的到时候再说吧