1、认识端口号
端口号(port)是传输层协议的内容
• 端口号是一个2字节16位的整数;
• 端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来 处理;
• IP地址+端口号能够标识网络上的某一台主机的某一个进程;
• 一个端口号只能被一个进程占用.
0-1023:知名端口号,HTTP,FTP,SSH等这些广为使用的应用层协议,他们的 端口号都是固定的.
1024-65535:操作系统动态分配的端口号.客户端程序的端口号,就是由操作 系统从这个范围分配的.
C++ socket n. (电源)插座;(电器上的)插口,插孔,管座;槽;窝;托座;臼;孔穴 vt. 把…装入插座;给…配插座
我们把ip+port叫做套接字socket 所以,网络通信的本质,也是进程间通信
2、TCP VS UDP
TCP 协议:传输层的有连接协议,能可靠传输,基于字节流工作
UDP 协议:传输层的无连接协议,传输不可靠,面向数据报
3. 网络字节
两个基础概念
计算机存储多字节数字有两种方式:假设数字0x1234(2 字节):
- 大端序(Big-Endian):高字节放低地址
12 34 - 小端序(Little-Endian):低字节放低地址
34 12
所有网络传输的数据,统一规定使用大端序
// h = host主机 n=network网络 s=short(2字节) l=long(4字节) htons() 主机短整型 → 网络字节序 htonl() 主机长整型 → 网络字节序 ntohs() 网络短整型 → 主机字节序 ntohl() 网络长整型 → 主机字节序单字节数据(char、uint8_t)不需要转换!只有short、int 这种多字节整数才需要转字节序。单个字节不存在高低字节问题。
字符串不需要字节序转换!字符串是连续单字节字符,不存在大小端问题。
❗很多新手踩坑:发送字符串调用 htons,完全错误。
- 只有自己组装二进制通信协议的时候才需要考虑。如果你只是用 send 发普通字符串(HTTP 请求等),不用管字节序。
4. 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);