1、close()
关闭文件描述符(包括 socket),立即关闭 socket,对该文件描述符进行“资源回收”。关闭 socket 文件描述符,释放操作系统资源。对于 TCP 连接,close()
会触发 TCP 的 四次挥手(FIN),通知对方你要断开连接。另外,如果对端还未接收数据,可能会造成 RST(重置连接),丢失数据,调用 close()
后该 socket_fd
无法再使用。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> // 包含 close() #include <arpa/inet.h> // 包含 socket 相关函数 int main() { int sockfd; struct sockaddr_in server_addr; char *message = "Hello, server!"; // 创建 socket sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket 创建失败"); exit(EXIT_FAILURE); } // 设置服务器地址 server_addr.sin_family = AF_INET; server_addr.sin_port = htons(8888); // 服务器端口 server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 本地服务器 // 连接服务器 if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("连接失败"); close(sockfd); // 连接失败时也要关闭 socket exit(EXIT_FAILURE); } // 发送消息 send(sockfd, message, strlen(message), 0); printf("消息已发送,关闭 socket。\n"); // 关闭 socket close(sockfd); return 0; }
2、shutdown()
shutdown()
函数用于 部分或完全关闭一个 socket 的连接。它比 close()
更灵活,可以单独关闭 读通道、写通道,或 全部关闭。
int shutdown(int sockfd, int how);
sockfd
套接字描述符,how
指定关闭的方式。常用的有:
SHUT_RD(0)
关闭读操作。不能再接收数据。
SHUT_WR(1)
关闭写操作。不能再发送数据。
SHUT_RDWR(2)
同时关闭读和写。
#include <stdio.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> int main() { int sock = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(12345); inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr); connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)); // 发送请求 const char *msg = "Hello, server!"; send(sock, msg, strlen(msg), 0); // 关闭写通道,告诉服务器不再发送数据 shutdown(sock, SHUT_WR); // 接收服务器回应 char buffer[1024]; int len = recv(sock, buffer, sizeof(buffer)-1, 0); buffer[len] = '\0'; printf("收到回应: %s\n", buffer); // 关闭 socket close(sock); return 0; }
3、close() 和 shutdown() 区别
close()
和 shutdown()
都用于关闭 socket
,但它们的行为和应用场景不同。
特性/行为 | close() | shutdown() |
作用范围 | 立即关闭 socket 的读写功能及释放文件描述符 | 按指定方式关闭 socket 的读/写功能,不立即释放描述符 |
关闭粒度 | 一刀切,不能细分 | 可选择关闭 读 、 写 、或 读写 通道 |
是否释放资源 | 是,释放文件描述符 | 否,仅关闭指定通道,仍需调用 close() 释放资源 |
是否可继续使用 | 否,调用后文件描述符无效 | 是,可根据关闭方式继续读或写 |
常见用途 | 程序结束时彻底释放 socket | 通讯中半关闭连接(如 TCP 四次挥手中的 FIN) |
系统调用行为 | 会递减引用计数,最后一个引用才会关闭连接 | 不影响引用计数,仅断开通道 |