這裏有一種方法來確定你的孩子是否你的文件描述符是套接字。
由於孩子要繼承fd表,只需遍歷FD來測試每個表。以下程序中的孩子通過getrlimit
獲取fd表的最大大小,並通過表遍歷表來確定每個文件描述符是否(a)打開,(b)套接字,如果是的話(c)是否是偵聽套接字。父母只是在分叉之前打開一個監聽和常規套接字(用於測試目的),然後等待孩子。
你應該能夠使用這個大綱來實現你的目標,而不訴諸於awk等。
#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <string.h>
#include <netdb.h>
int isListeningSocket(int fd)
{
int retval;
socklen_t len = sizeof(retval);
if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &retval, &len) != -1)
if (retval)
return(1);
return(0);
}
int main (int argc, char *argv[])
{
//create a listening socket
int lsock = socket(AF_INET,SOCK_STREAM, 0);
struct sockaddr_in serverinfo;
memset(&serverinfo, '0', sizeof(serverinfo));
serverinfo.sin_family=AF_INET;
serverinfo.sin_port=htons(atoi("9999"));
serverinfo.sin_addr.s_addr=INADDR_ANY;
int ret;
if ((ret = bind(lsock,(struct sockaddr *) &serverinfo, sizeof(serverinfo))) == -1)
{
perror("bind");
exit(1);
}
if ((ret = listen(lsock,1000)) == -1)
{
perror("listen");
exit(1);
}
//create a regular socket
int rsock = socket(AF_INET,SOCK_STREAM, 0);
int pid = fork();
if (pid == -1)
{
perror("fork");
exit(1);
}
if (pid) //parent
{
wait(NULL);
exit(0);
}
//child ----------
struct rlimit rlim;
if ((ret = getrlimit(RLIMIT_NOFILE, &rlim)) == -1)
{
perror("getrlimit");
exit(1);
}
int maxFD = rlim.rlim_cur;
for (int i = 0; i < maxFD; ++i)
{
struct stat statbuf;
if (fstat(i, &statbuf) == -1)
if (errno == EBADF)
{
printf("file descriptor %d is not open\n", i);
continue;
}
else
{
perror("fstat");
exit(1);
}
if (S_ISSOCK(statbuf.st_mode))
if (isListeningSocket(i))
printf("file descriptor %d is a LISTENING socket\n", i);
else
printf("file descriptor %d is a REGULAR socket\n", i);
else
printf("file descriptor %d is NOT a socket\n", i);
}
return 0;
}
我不確定這是可能的,而不需要編輯父進程代碼。每當我遇到這個問題時,我都使用了你不需要的解決方案2。 –
一種可能的方法,如果使用Linux:檢查/ proc//fd /中的鏈接。關閉鏈接到「socket:[inode]」的描述符。 –
我懷疑你錯誤診斷了根本原因,現在正在考慮解決你自己製造問題的兩種不良解決方案。對於孩子來說,關閉監聽套接字並讓父母在分叉之後立即關閉數據套接字應該是微不足道的。 – Duck