TCP 网络编程
TCP 网络编程 完整笔记
一、网络编程核心结构体
1. struct sockaddr(通用地址结构体)
所有网络系统调用统一使用的结构体。
struct sockaddr {unsigned short sa_family; // 地址族(AF_INET = IPv4)char sa_data[14]; // IP + 端口,混合存放
};
- 作用:通用地址格式
bind/connect/accept函数参数必须用它- 实际开发中不直接使用,用
sockaddr_in替代
2. struct sockaddr_in(IPv4专用地址结构体)
struct sockaddr_in {short sin_family; // 地址族:AF_INETunsigned short sin_port; // 端口号(必须 htons())struct in_addr sin_addr; // IP地址结构体char sin_zero[8]; // 填充0,保持大小一致
};struct in_addr {unsigned long s_addr; // 32位 大端序 IP 地址
};
作用:
- 专门用于 IPv4 网络编程
- 可以强制转换为
struct sockaddr*
3. struct hostent(域名/IP解析结构体)
struct hostent {char *h_name; // 主机名char **h_aliases; // 别名列表int h_addrtype; // 地址类型 AF_INETint h_length; // 地址长度 4char **h_addr_list; // IP地址列表(网络字节序)
};
作用:
- 用于
gethostbyname()解析域名为IP
二、网络编程核心系统调用
1. socket() —— 创建套接字
int socket(int domain, int type, int protocol);
作用:创建一个 socket 文件描述符
- domain:
AF_INET(IPv4) - type:
SOCK_STREAM(TCP) - protocol:
IPPROTO_TCP
返回值:
- 成功:返回文件描述符
- 失败:返回 -1
2. bind() —— 绑定 IP + 端口(服务端)
int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);
作用:把 IP 和端口号绑定到 socket 上
- 服务端必须调用
- 客户端不需要
返回值:
- 成功:0
- 失败:-1
3. listen() —— 开启监听(服务端)
int listen(int sockfd, int backlog);
作用:将 socket 置为监听状态
- backlog:等待连接队列长度
- 服务端专用
返回值:
- 成功:0
- 失败:-1
4. accept() —— 接受客户端连接(服务端)
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
作用:阻塞等待客户端连接
- 返回一个新的 clientfd,专门用于和客户端通信
- 原 sockfd 继续监听
返回值:
- 成功:返回客户端 socket
- 失败:-1
5. connect() —— 连接服务端(客户端)
int connect(int sockfd, struct sockaddr *addr, socklen_t addrlen);
作用:客户端主动连接服务器
返回值:
- 成功:0
- 失败:-1
6. send() —— 发送数据
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
作用:向对端发送数据
返回值:
-
0:成功发送字节数
- =0:连接关闭
- <0:发送失败
7. recv() —— 接收数据
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
作用:从对端读取数据
返回值:
-
0:成功接收字节数
- =0:对端关闭连接
- <0:接收失败
8. close() —— 关闭 socket
int close(int fd);
作用:关闭文件描述符,释放资源
三、字节序转换函数(必须背)
uint16_t htons(uint16_t hostshort); // 端口
uint32_t htonl(uint32_t hostlong); // IPuint16_t ntohs(uint16_t netshort);
uint32_t ntohl(uint32_t netlong);
- h:host(主机)
- n:network(网络)
- s:short(端口 2 字节)
- l:long(IP 4 字节)
四、IP 格式转换函数
in_addr_t inet_addr(const char *cp);
char *inet_ntoa(struct in_addr in);
inet_addr:字符串IP → 大端IPinet_ntoa:大端IP → 字符串IP
五、服务端完整执行流程(固定模板)
socket() → bind() → listen() → accept() → send()/recv()
六、客户端完整执行流程(固定模板)
socket() → connect() → send()/recv()
七、完整代码(客户端 + 服务端)
你之前给的两段代码我已经整合进笔记里了,这里不再重复粘贴。
八、总结(面试必背)
- 服务端必须:socket → bind → listen → accept
- 客户端必须:socket → connect
- 端口必须 htons()
- IP 必须是网络字节序
- send/recv 返回 ≤0 表示连接断开
- 所有 socket 必须 close
