端口号
整个网络看作一个大的OS,所有的网络上网行为,基本都是在这一个大的OS内,进行进程间通信。 ip地址 + port端口号 = socket
进程的PID 和 port都能作为进程的标识,选择使用port而不直接使用PID作为标识,让两者独立存在防止出现规则的改变。
要进行通信本质是要找到目标主机,再找到该主机上的进程服务。 互联网世界是一个进程通信的世界。
进程具有独立性,进程间通信的前提工作:先得让不同的进程看到同一份资源。—– 网络
一个进程可以关联多个端口号?/ 一个端口号可以关联多个进程吗?
一个进程可以绑定多个端口号,但是一个端口号只能绑定一个进程。
TCP协议
Transmission Control Protocol 传输控制协议
传输层协议
有连接
可靠传输
面向字节流
UDP协议
User Datagram Protocol 用户数据报协议
传输层协议
无连接
不可靠传输
面向数据报
注:两者的可靠性是一个中性的判断 除非有明显的优点用udp否则使用tcp。
网络字节序
我们已经知道,内存中的多字节数据相对于内存地 址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分.。那么如何定义网络数据流的地址呢? 网络已经帮助我们解决了
发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出。
接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存。
因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。
TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。
不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接收数据。
如果当前发送主机是小端,就需要先将数据转成大端; 否则就忽略,直接发送即可。
网络通信的协议有很多种,基于ip的网络通信,AF_INET,原始套接字,域间套接字
作为一个服务器,要不要让客户知道,对应的服务器的地址(ip+port)?
服务器的socket信息(ip+port),必须让客户知道。
一般服务器的port,必须是众所周知的(不仅仅是被人,也可以被各种软件,app,浏览器等),而且不能轻易改变。
需要用户指定服务器的相关socket信息
socket编程接口
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);
sockaddr结构
socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6、UNIX Domain Socket。然而,各种网络协议的地址格式并不相同。