Socket-Optionsfunktion Funktion: Methoden zum Lesen und Setzen von Socket-Dateideskriptorattributen #include <sys/scoket.h> int getsockopt (int sockfd, int level, int option_name, void* option_value, socklen_t* restrict option_len); int setsockopt (int sockfd, int level, int option_name, const void* option_value, socklen_t option_len); Die Socket-Optionstabelle sieht wie folgt aus: Die Funktionen getsockopt und setsockopt geben bei Erfolg 0 und bei einem Fehler -1 zurück und setzen errno. Für den Server sind einige Socket-Optionen nur gültig, wenn sie vor dem Aufruf des Listen-Systemaufrufs für den Listening-Socket festgelegt wurden. Dies liegt daran, dass der Verbindungs-Socket nur durch den Accept-Aufruf zurückgegeben werden kann und die durch Accept aus der Abhörwarteschlange akzeptierte Verbindung mindestens die ersten beiden Schritte des TCP-Drei-Wege-Handshakes abgeschlossen hat (da die Verbindung in der Abhörwarteschlange mindestens den Status SYN_RCVD erreicht hat). Dies bedeutet, dass der Server ein TCP-Synchronisierungssegment an die empfangene Verbindung gesendet hat. Allerdings sollten einige Socket-Optionen im TCP-Synchronisierungssegment festgelegt werden, z. B. die TCP-Maximalsegmentoption. Für diese Situation bietet Linux Entwicklern die folgende Lösung: Legen Sie diese Socket-Optionen für den Listening-Socket fest. Anschließend erbt der von Accept zurückgegebene Verbindungs-Socket diese Optionen automatisch. Diese Optionen sind: SO_DEBUG, SO_DONTROUTE, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_RCVBUF, SO_RCVLOWAT, SO_SNDBUF, SO_SNDLOWAT, TCP_MAXSEG und TCP_NODELAY. Für den Client sollten diese Socket-Optionen vor dem Aufruf der Verbindungsfunktion festgelegt werden, da nach der erfolgreichen Rückgabe des Verbindungsaufrufs der TCP-Drei-Wege-Handshake abgeschlossen ist. SO_REUSEADDR-Option Wir haben den TIME_WAIT-Status von TCP-Verbindungen bereits besprochen und erwähnt, dass das Serverprogramm durch Festlegen der Socket-Option SO_REUSEADDR die Verwendung der von der Verbindung im TIME_WAIT-Status belegten Socket-Adresse erzwingen kann. #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <string.h> int main( int argc, char* argv[] ) { wenn(argc <= 2) { printf( "Verwendung: %s IP-Adresse Portnummer\n", Basisname( argv[0] ) ); Rückgabe 1; } const char* ip = argv[1]; Port wird als Portnummer bezeichnet. int sock = socket( PF_INET, SOCK_STREAM, 0 ); behaupten( Socke >= 0 ); int Wiederverwendung = 1; setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &wiederverwenden, sizeof( wiederverwenden ) ); Struktur sockaddr_in Adresse; bzero( &Adresse, Größe von(Adresse)); Adresse.sin_family = AF_INET; inet_pton( AF_INET, ip, &Adresse.sin_addr ); Adresse.sin_port = htons(Port); int ret = bind(sock, (Struktur sockaddr*)&Adresse, sizeof(Adresse)); behaupten( ret != -1 ); ret = listen( Socke, 5 ); behaupten( ret != -1 ); Struktur sockaddr_in Client; socklen_t client_addrlength = Größe von (Client); int connfd = akzeptieren( sock, ( Struktur sockaddr* )&client, &client_addrlength ); wenn ( connfd < 0 ) { printf( "fehlernummer ist: %d\n", errno ); } anders { Zeichen Remote [INET_ADDRSTRLEN]; printf( "verbunden mit IP: %s und Port: %d\n", inet_ntop( AF_INET, &client.sin_addr, remote, INET_ADDRSTRLEN ), ntohs( client.sin_port ) ); schließen( connfd ); } schließen (Socke); gebe 0 zurück; } Nachdem setsocketopt festgelegt wurde, kann die daran gebundene Socket-Adresse sofort wiederverwendet werden, auch wenn sich der Sock im Status TIME_WAIT befindet. Darüber hinaus können wir geschlossene Sockets auch schnell wiederverwenden, indem wir den Kernelparameter /proc/sys/net/ipv4/tcp_tw_recycle ändern, sodass die TCP-Verbindung überhaupt nicht in den Zustand TIME_WAIT wechselt und die Anwendung die lokale Socket-Adresse sofort wiederverwenden kann. Optionen SO_RCVBUF und SO_SNDBUF Die Optionen SO_RCVBUF und SO_SNDBUF stellen die Größen des TCP-Empfangspuffers bzw. des Sendepuffers dar. Wenn wir jedoch setsockopt verwenden, um die Größe des TCP-Empfangspuffers und des Sendepuffers festzulegen, verdoppelt das System seinen Wert und er darf nicht kleiner als sein Mindestwert sein. Der Mindestwert für den TCP-Empfangspuffer beträgt 256 Byte und der Mindestwert für den Sendepuffer beträgt 2048 Byte (verschiedene Systeme können jedoch unterschiedliche Standardmindestwerte haben). Darüber hinaus können wir die Kernelparameter /proc/sys/net/ipv4/tcp_rmem und /proc/sys/net/ipv4/tcp_wmem direkt ändern, um zu erzwingen, dass der TCP-Empfangspuffer und der Sendepuffer keine Mindestgrößenbeschränkung haben. Ändern Sie das Client-Programm des TCP-Sendepuffers: #include <sys/socket.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #define BUFFER_SIZE 512 int main( int argc, char* argv[] ) { wenn(argc <= 3) { printf( "Verwendung: %s IP-Adresse Portnummer Sendepuffergröße\n", Basisname( argv[0] ) ); Rückgabe 1; } const char* ip = argv[1]; Port wird als Portnummer bezeichnet. Struktur sockaddr_in Serveradresse; bzero( &Serveradresse, Größe von( Serveradresse ) ); server_address.sin_family = AF_INET; inet_pton( AF_INET, ip, &Serveradresse.sin_addr ); server_address.sin_port = htons(Port); int sock = socket( PF_INET, SOCK_STREAM, 0 ); behaupten( Socke >= 0 ); int sendbuf = atoi( argv[3] ); int len = sizeof( sendbuf ); setsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, sizeof( sendbuf ) ); getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, ( socklen_t* )&len ); printf( "die Größe des TCP-Sendepuffers nach der Einstellung ist %d\n", sendbuf ); wenn (Verbinden(Sock, (Struktur Sockaddr*)&Serveradresse, Größe von(Serveradresse)) != -1) { Zeichenpuffer [PUFFERGRÖSSE]; memset(Puffer, „a“, PUFFERGRÖSSE); sende(sock, puffer, PUFFERGRÖSSE, 0); } schließen (Socke); gebe 0 zurück; } Ändern Sie das Serverprogramm des TCP-Empfangspuffers: #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <string.h> #define BUFFER_SIZE 1024 int main( int argc, char* argv[] ) { wenn(argc <= 3) { printf( "Verwendung: %s IP-Adresse Portnummer Empfangspuffergröße\n", Basisname( argv[0] ) ); Rückgabe 1; } const char* ip = argv[1]; Port wird als Portnummer bezeichnet. Struktur sockaddr_in Adresse; bzero( &Adresse, Größe von(Adresse)); Adresse.sin_family = AF_INET; inet_pton( AF_INET, ip, &Adresse.sin_addr ); Adresse.sin_port = htons(Port); int sock = socket( PF_INET, SOCK_STREAM, 0 ); behaupten( Socke >= 0 ); : In diesem Fall wird die Anweisung recvbuf = atoi( argv[3] ); int len = sizeof(recvbuf); setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, sizeof( recvbuf ) ); getsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, ( socklen_t* )&len ); printf( "die Größe des Empfangspuffers nach dem Einstellen ist %d\n", recvbuf ); int ret = bind(sock, (Struktur sockaddr*)&Adresse, sizeof(Adresse)); behaupten( ret != -1 ); ret = listen( Socke, 5 ); behaupten( ret != -1 ); Struktur sockaddr_in Client; socklen_t client_addrlength = Größe von (Client); int connfd = akzeptieren( sock, ( Struktur sockaddr* )&client, &client_addrlength ); wenn ( connfd < 0 ) { printf( "fehlernummer ist: %d\n", errno ); } anders { Zeichenpuffer [PUFFERGRÖSSE]; memset(Puffer, '\0', PUFFERGRÖSSE); während (recv (connfd, Puffer, Puffergröße-1, 0) > 0) {} schließen(connfd); } schließen (Socke); gebe 0 zurück; } Laufergebnisse:
Wie oben erklärt: Wenn wir setsockopt verwenden, um die Größe des TCP-Empfangspuffers und des Sendepuffers festzulegen, verdoppelt das System seinen Wert und er darf nicht kleiner als sein Mindestwert sein. Optionen SO_RCVLOWAT und SO_SNDLOWAT
SO_LINGER-Option Die Option SO_LINGER wird verwendet, um das Verhalten des Systemaufrufs „Close“ beim Schließen einer TCP-Verbindung zu steuern. Wenn wir den Systemaufruf „close“ zum Schließen eines Sockets verwenden, wird „close“ standardmäßig sofort zurückgegeben, und das TCP-Modul ist dafür verantwortlich, die verbleibenden Daten im dem Socket entsprechenden TCP-Sendepuffer an die andere Partei zu senden. Wenn wir den Wert der Option SO_LINGER festlegen, müssen wir dem Systemaufruf setsockopt (getsockopt) eine Struktur vom Typ Linger übergeben, die wie folgt definiert ist: #include <sys/socket.h> Struktur verweilen { int l_onoff; //Diese Option ein- (ungleich 0) oder ausschalten (0) int l_linger; //Verweildauer};
Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird. Das könnte Sie auch interessieren:
|
<<: Vue verwendet dynamische Komponenten, um einen TAB-Umschalteffekt zu erzielen
>>: Centos7-Installation und Konfiguration von Mysql5.7
Inhaltsverzeichnis 1. Anwendung und Konfiguration...
1. Einführung in Flex Layout Flex ist die Abkürzu...
Problemdatensatz Heute wollte ich ein kleines Bau...
Bevor wir über die CSS-Priorität sprechen, müssen...
Vorwort Wir alle wissen, dass man QR-Codes in off...
Nach den Änderungen: innodb_buffer_pool_size=576M...
<style type="text/css"> Code kopie...
erster Schritt Einmaliges Löschen mit der integri...
Dieser Effekt tritt am häufigsten auf unserer Bro...
Die Front-End- und Back-End-Projekte sind getrenn...
1. Erzielen Sie den Effekt 2 Wissenspunkte 2.1 &l...
Finden Sie das Problem Beim Abrufen der wichtigst...
In diesem Artikel wird der spezifische Code der m...
1. Zwei Eigenschaften des Tabellen-Resets: ①borde...
In MySQL können Sie die Funktionen IF(), IFNULL()...