
场景1:
应用程序创建了socket,但是当作为client端时没有调用connect去连接server端:
模拟构造问题现象程序:
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
int sockfd[16] = {0};
int i=0;
for(i=0;i<16;i++)
{
sockfd[i] = socket(AF_INET,SOCK_STREAM,0);
if (sockfd[i] == -1){
printf("Fail to create a socket.");
}
}
while(1)
sleep(10);
}
场景二:
client端连接server端后,三次握手连接已经建立了,然后client端发起关闭连接,server端也不做关闭连接处理,最后连接被client端rst掉,导致fd还在,但是netstat看到连接不存在。
模拟构造问题现象:
1 先运行server端程序./server
2 client端发起连接前状态

3. client端发起连接后状态:

4. 连接被关闭后netstat查看tcp连接已经不存在,但是fd还在

构造问题现象代码实例:
server端:
# cat server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 5) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen);
if (new_socket < 0) {
perror("accept failed");
exit(EXIT_FAILURE);
}
read(new_socket, buffer, BUFFER_SIZE);
printf("Message received: %s\n", buffer);
sleep(120);
write(new_socket, buffer, BUFFER_SIZE);
while(1)
sleep(10);
return 0;
}client端:
# cat client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sock = 0;
struct sockaddr_in serv_addr;
char *message = "Hello from client";
char buffer[BUFFER_SIZE] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
perror("invalid address");
exit(EXIT_FAILURE);
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("connection failed");
exit(EXIT_FAILURE);
}
send(sock, message, strlen(message), 0);
printf("Message sent\n");
sleep(60);
// Abnormal connection termination
shutdown(sock, SHUT_RDWR);
close(sock);
return 0;
}场景3:
client端connect失败后未主动关闭连接导致fd泄露
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX_ATTEMPTS 100 // 尝试创建 100 个 socket
#define UNREACHABLE_IP "192.0.2.1" // 测试用不可达 IP (RFC 5737)
#define UNREACHABLE_PORT 12345 // 测试用不可达端口
int main() {
int sockfd;
struct sockaddr_in serv_addr;
printf("PID = %d\n", getpid());
printf("Run `ls -l /proc/%d/fd` to check leaked file descriptors.\n", getpid());
printf("Press Enter to start...");
getchar();
for (int i = 0; i < MAX_ATTEMPTS; i++) {
// 创建 TCP socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket() failed");
exit(EXIT_FAILURE);
}
// 设置目标地址(不可达)
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(UNREACHABLE_PORT);
if (inet_pton(AF_INET, UNREACHABLE_IP, &serv_addr.sin_addr) <= 0) {
perror("inet_pton() failed");
exit(EXIT_FAILURE);
}
// 尝试连接(预期失败)
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("[%d] connect() failed: %s\n", i, strerror(errno));
// 故意不调用 close(sockfd),模拟 fd 泄漏!
} else {
printf("[%d] connect() succeeded (unexpected)\n", i);
close(sockfd); // 如果意外成功,关闭 socket
}
}
printf("Done. Check `ls -l /proc/%d/fd` for leaked file descriptors.\n", getpid());
printf("Press Enter to exit...");
getchar();
return 0;
}



待续.........................
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。