Sie haben nicht das genaue Betriebssystem angegeben, das Sie verwenden. Ich habe herausgefunden, dass Linux einen API-Aufruf hat, der eine TCP-Verbindung zurücksetzt, ich habe keine Ahnung, wie portabel es ist. Der Weg dazu besteht darin, den Systemaufruf connect
auf dem bereits verbundenen Socket zu verwenden, diesmal jedoch mit der Familie AF_UNSPEC
.
Nachdem Sie einen Socket auf diese Weise zurückgesetzt haben, ist es sogar möglich, den Socket erneut mit einem anderen connect
Aufruf zu verbinden.
int main(int argc, char** argv)
{
int fd = socket(AF_INET6, SOCK_STREAM, 0);
while (1) {
struct sockaddr_in6 sockaddr = {
.sin6_family = AF_INET6,
.sin6_port = htons(80),
.sin6_flowinfo = 0,
.sin6_scope_id = 0,
};
struct timespec s = {
.tv_sec = 2,
.tv_nsec = 0,
};
/* Connect to port 80 on localhost */
inet_pton(AF_INET6, "::1", &sockaddr.sin6_addr.s6_addr);
connect(fd, (struct sockaddr*)&sockaddr,sizeof(sockaddr));
nanosleep(&s, NULL);
/* Reset previously connected socket */
sockaddr.sin6_family = AF_UNSPEC;
connect(fd, (struct sockaddr*)&sockaddr,sizeof(sockaddr));
nanosleep(&s, NULL);
}
}
AFAIK, es gibt keine Möglichkeit, dies mit dem Socket zu tun, den Sie gesendet und empfangen haben. Du könntest immer dein eigenes RST-Paket herstellen und es an deinen Partner schicken, aber du müsstest einen separaten rohen Paket-Socket erstellen, um es zu senden. Linux hat auch eine "SOCK_DESTROY" -Funktion (bedingt im Kernel enthalten), die von einem entsprechend privilegierten Prozess verwendet werden kann, um eine beliebige Verbindung zu schließen, aber es ist auch völlig out-of-band von Ihrem Anwendungs-Socket. Warum möchten Sie trotzdem mit RST terminieren? –
Sie können versuchen, SO_LINGER Socket-Option mit Null-Timeout, [nach einigen Ressourcen] (http://stackoverflow.com/questions/3757289/tcp-option-so-linger-zero-when-its-required) wird es RST generieren Paket statt FIN. –
@SlavaBacherikov danke, es funktioniert in Code: '$ Socket = IO :: Socket :: INET-> neu (Listen = 1, ReuseAddr => 1, LocalPort => ..., ...); $ client = $ socket-> accept(); $ client-> sockopt (SO_LINGER, pack ('II', 1, 0)); Schließen Sie $ client'. curl und wget behandeln diese Bedingung immer mit Rückgabecode 56 bzw. 4. netcat erkennt jedoch nichtdeterministisch irgendwann "Verbindung wird von Peer abgelehnt", aber manchmal nicht. – bandie