1 socket()
创建通信工具
int socket(int domain, int type, int protocol);
| domain | AF_INET AF_INET6 AF_UNIX |
|---|---|
| type | SOCK_STREAM(TCP) SOCK_DGRAM(UDP) |
| protocol | 一般为0,即让系统根据前面的 domain + type 自动选择合适的协议 |
| – | – |
2 sockaddr_in
描述“对方是谁”
struct sockaddr_in server;
其专门用来描述IPv4地址+端口
| sin_family | IPv4地址 |
|---|---|
| sin_port | 服务端口号 |
| sin_addr | IP地址 |
| – | – |
同时,一般会 sockaddr_in server{}; 来初始化这个结构体
3 sendto()
给对方发数据
ssize_t sendto
(
int sockfd,
const voidbuf,
size_t len,
int flags,
const struct sockaddrdest_addr,
socklen_t addrlen
);
4 recvfrom()
接收对方的数据
ssize_t recvfrom
(
int sockfd,
voidbuf,
size_t len,
int flags,
struct sockaddrsrc_addr,
socklen_taddrlen
);
5 close()
用完关闭 socket
6int bind(int sockfd,
const struct sockaddraddr,
socklen_t addrlen);
7int listen(int sockfd, int backlog);
把一个主动的 TCP Socket 变成一个“等待客户端连接”的监听 Socket,其中backlog表示允许操作系统维护一定数量的等待连接
8int accept(int sockfd,
struct sockaddraddr,
socklen_taddrlen);*
监听 Socket 和通信 Socket 是两个不同的东西,在listen之后,accept会返回一个新的socket.
9int connect(int sockfd,
const struct sockaddraddr,
socklen_t addrlen);
htons()主机字节序转网络字节序
uint16_t htons(uint16_t hostshort);
不同CPU对多字节数字的存储方式可能不同,所以网络协议统一规定网络字节序使用大端序
对应的ntohs()就是网络到主机的转换,除了16位的,还有针对32位的htonl()和ntohl()
inet_addr()把IP字符串转换成网络地址,由于给到的地址通常是字符串,而网络层需要的是二进制形式的(通常搭配c_str()把std::string转换成const char*类型的)
其中TCP需要建立连接而UDP不需要,所以UDP发送和接收比TCP多一个包含发送/接收信息对象的结构
客户端采用随机端口的方式解决客户端端口冲突的问题