Wie man etablierte TCP -Verbindungen zu Ghost Sockets verhindern, die keinen Dateideskriptor haben [geschlossen]Linux

Linux verstehen
Anonymous
 Wie man etablierte TCP -Verbindungen zu Ghost Sockets verhindern, die keinen Dateideskriptor haben [geschlossen]

Post by Anonymous »

Ich habe einen Multi-Thread-Test, der auf Localhost eine Reihe von TCP-Verbindungen für sich selbst herstellt. Das Problem, das ich habe, ist, dass einige der aktiven Opener im etablierten Zustand verbleiben, obwohl sie keinen zugeordneten Dateideskriptor haben. Hier ist ein minimales nicht arbeitendes Beispiel in C ++: < /p>

Code: Select all

#include 
#include 
#include 

#include 
#include 
#include 
#include 

void
do_accept(int lfd)
{
sockaddr_in sin;
socklen_t sinlen = sizeof(sin);
int fd = accept(lfd, (sockaddr *) &sin, &sinlen);

close(lfd);

char buf[128];
errno = 0;
while (read(fd, buf, sizeof(buf)) > 0)
;
close(fd);
}

void
do_poll(int cfd, int wake)
{
pollfd pfds[2];
pfds[0].fd = cfd;
pfds[0].events = POLLIN;
pfds[1].fd = wake;
pfds[1].events = POLLIN;
poll(pfds, 2, -1);
}

int
main()
{
int lfd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in sin{};
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
bind(lfd, (sockaddr *)&sin, sizeof(sin));
listen(lfd, 5);

socklen_t sinlen = sizeof(sin);
getsockname(lfd, (sockaddr *)&sin, &sinlen);
uint16_t port = ntohs(sin.sin_port);

std::println("listening on port {}", port);
std::thread acceptor(do_accept, lfd);

int cfd = socket(AF_INET, SOCK_STREAM, 0);
if (connect(cfd, (sockaddr *)&sin, sinlen)) {
perror("connect");
exit(1);
}

int selfpipe[2];
pipe(selfpipe);
std::thread poller(do_poll, cfd, selfpipe[0]);
poll(nullptr, 0, 1000);

//shutdown(cfd, SHUT_WR); // Works if you uncomment
close(cfd);           // Would like this to send EOF
acceptor.join();      // Would like this to return

std::println("Will never get this far");
write(selfpipe[1], "", 1);
poller.join();
}
< /code>
Dieses Programm erstellt einen "Ghost Socket", dessen Dateideskriptor damit zugeordnet ist.  Sie können dies mit den Befehlen ss 
und lSOF überprüfen. Zum Beispiel: < /p>
$ lsof -c closepoll -nPa -i tcp -Tqs
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
closepoll 918275 user 5u IPv4 8515786 0t0 TCP 127.0.0.1:41503->127.0.0.1:57248 (ESTABLISHED QR=0 QS=0)
$ ss -antp "sport 57248 or dport 57248"
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 127.0.0.1:57248 127.0.0.1:41503
ESTAB 0 0 127.0.0.1:41503 127.0.0.1:57248 users:(("closepoll",pid=918275,fd=5))
< /code>
Kein Dateideskriptor entspricht dem lokalen Port 57248, obwohl es sich um eine Verbindung im festgelegten Zustand handelt. Sollte es nicht eingeben fin_wait_1, wenn der letzte Dateideskriptor geschlossen ist? und wie kann ich dieses Problem vermeiden?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post