Ich habe versucht, meinen Socket (Server-Socket) an Portnummer 8000
zu binden. Es hat funktioniert und die Arbeit für mich erledigt. Am Ende des Codes schließe ich auch die Steckdose. Schon beim nächsten Mal führe ich meinen Code erneut aus und es zeigt mir, dass die Adresse bereits verwendet wird. Ich habe die Bedeutung der Fehlerwerte strerror(errno);
ausgedruckt, um zu sehen, ob mein Code an jedem Punkt ordnungsgemäß funktioniert. Um zu überprüfen, ob der Port frei ist, habe ich ihn mit netstat
geprüft, aber die Portnummer 8000
ist frei. Bei mir ist es oft passiert. Ich warte jedes Mal ein paar Sekunden und dann geht es wieder los. Ich verwende c-Sprache. Was ist der Grund für dieses Verhalten meines Betriebssystems?.
Nach ein paar Sekunden führe ich den Code aus und dann funktioniert es.
[email protected]:~/Desktop/testing$ Sudo ./a.out
Socket Creation: Success
File open: Success
Socket Bind: Address already in use
Socket Listen: Address already in use
^C
[email protected]:~/Desktop/testing$ Sudo netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1348/lighttpd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 984/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 1131/cupsd
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1211/mysqld
tcp6 0 0 :::22 :::* LISTEN 984/sshd
tcp6 0 0 ::1:631 :::* LISTEN 1131/cupsd
[email protected]:~/Desktop/testing$ Sudo ./a.out
Socket Creation: Success
File open: Success
Socket Bind: Address already in use
Socket Listen: Address already in use
^C
[email protected]:~/Desktop/testing$
Ich bin auch in die gleiche Frage geraten. Dies liegt daran, dass Sie die Verbindung zum Sockel schließen, nicht jedoch den Sockel. Der Socket kann in den Status TIME_WAIT wechseln (um sicherzustellen, dass alle Daten übertragen wurden, garantiert TCP die Zustellung wenn möglich) und es dauert bis zu 4 Minuten, bis freigegeben wird.
oder, für eine wirklich detaillierte/technische Erklärung, überprüfen Sie diesen Link
Es kann ärgerlich sein, um sicher zu sein, aber es gibt keinen richtigen Weg und es ist kein Fehler.
Ich weiß, es ist eine Weile her, seit die Frage gestellt wurde, aber ich konnte eine Lösung finden:
int sockfd;
int option = 1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
Damit ist die Steckdose sofort wieder verwendbar.
Ich entschuldige mich, wenn dies "falsch" ist. Ich bin nicht sehr erfahren mit Steckdosen
Versuchen Sie netstat wie folgt: netstat -ntp
, ohne -l
. Es zeigt die TCP-Verbindung im TIME_WAIT
-Zustand.
Wie bereits erwähnt, ist Ihr Sockel wahrscheinlich im TIME_WAIT
-Zustand. Dieses Problem wird von Thomas A. Finehier beschrieben.
Um es zusammenzufassen, folgen Sie dem nachstehenden Diagramm:
Thomas sagt:
Wenn Sie das Diagramm oben betrachten, ist es klar, dass
TIME_WAIT
.__ sein kann. vermieden, wenn das entfernte Ende die Schließung einleitet. So kann der Server Vermeiden Sie Probleme, indem Sie den Client zuerst schließen. Die Anwendung Das Protokoll muss so ausgelegt sein, dass der Client weiß, wann geschlossen werden soll. Das Der Server kann jedoch sicher als Antwort auf ein EOF vom Client geschlossen werden Es muss auch ein Timeout festgelegt werden, wenn im Fall .__ ein EOF erwartet wird. Der Client hat das Netzwerk ungekünstelt verlassen. In vielen Fällen einfach Warten einige Sekunden, bevor der Server geschlossen wird, ist ausreichend.
Die Verwendung von SO_REUSEADDR
wird häufig im Internet vorgeschlagen, aber Thomas fügt hinzu:
Seltsamerweise kann die Verwendung von
SO_REUSEADDR
tatsächlich zu schwierigeren Fehlern bei der "Adresse Bereits verwendet" führen. MitSO_REUSADDR
können Sie einen Port verwenden, der .__ ist. inTIME_WAIT
stecken, aber Sie können diesen Port immer noch nicht verwenden, um eine .__ zu erstellen. Verbindung mit dem letzten Ort, an dem es verbunden ist. Was? Angenommen, ich wähle lokaler Port 1010 und stellen Sie eine Verbindung zu foobar.com-Port 300 her, und schließen Sie dann lokal, den Port inTIME_WAIT
belassen. Ich kann den lokalen Port 1010 .__ wiederverwenden. sofort für Verbindungen mitfoobar.com
port 300.
Schreib einfach
unlink [SOCKET NAME]
im terminal sollte dann der fehler nicht mehr existieren.
Selbst die Antwort von icfantv auf diese Frage ist bereits perfekt, ich habe noch weitere Ergebnisse in meinem Test.
Als Server-Socket im Abhörstatus, wenn er nur im Abhörstatus ist und sogar Anforderungen akzeptiert und Daten von der Clientseite abruft, jedoch ohne das Senden von Daten. Wir könnten den Server trotzdem sofort neu starten, nachdem er gestoppt wurde. Wenn jedoch auf der Serverseite Daten an den Client gesendet werden, wird beim Neustart desselben Diensts (gleicher Port) folgender Fehler angezeigt: (Adresse wird bereits verwendet).
Ich denke, das liegt an den TCP/IP-Designprinzipien. Wenn der Server die Daten an den Client zurücksendet, muss er sicherstellen, dass das Senden der Daten erfolgreich ist. Dazu muss das Betriebssystem (Linux) die Verbindung überwachen, auch wenn die Serveranwendung diesen Socket geschlossen hat .. __ Ich glaube trotzdem, Kernel-Socket Designer könnte dieses Problem verbessern.
der Fehler, den ich erhielt, war:
cockpit.socket: Failed to listen on sockets: Address already in use
das Update, das ich entdeckte, ist:
in/usr/lib/systemd/system/cockpit-Dienst habe ich die -Zeile geändert:
#ExecStartPre=/usr/sbin/remotectl certificate --ensure --user=root --group=cockpit-ws --selinux-type=etc_t
zu:
#ExecStartPre=/usr/sbin/remotectl certificate --ensure --user=root --group=cockpit-ws
wie Sie sehen, habe ich das Argument über Selinux herausgenommen. Dann lief ich:
systemctl daemon-reload
systemctl start cockpit.service
dann habe ich gesucht:
Ich akzeptierte das selbstsignierte Zertifikat und konnte sich erfolgreich im Cockpit anmelden und es normal verwenden.
dies ist alles auf einer Fedora25-Maschine. Der 9090-Port wurde bereits mit firewall-cmd
hinzugefügt.
Für AF_UNIX können Sie call unlink (path) verwenden. nach close () Socket in der "Server" -App