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
MySQL 8.0: MVCC für große Objekte in InnoDB In di...
/******************** * Zeichengerätetreiber*****...
Vorwort Nach der Bereitstellung des Servers besuc...
Wenn Sie das Win10-System installiert haben und e...
Inhaltsverzeichnis 01 Unsichtbare Spalten erstell...
Wenn Sie VMware Workstation zum Öffnen einer virt...
Was sind Slots? Wir wissen, dass in Vue nichts in...
Inhaltsverzeichnis 1. Projektkonstruktion 2: Verz...
<br />Worte sind das unvermeidliche Produkt ...
1. Qualitative Änderungen durch CSS-Variablen Die...
Ergebnis:Implementierungscode html <nav class=...
01. Unendlichkeit Schriftart herunterladen 02. Ban...
Inhaltsverzeichnis 1. Komponentenregistrierung 2....
Der gesamte Inhalt dieses Blogs ist unter Creativ...
Als ich den Dienst täglich überprüfte und mir die...