Junge Leute warnen
Persönliche Fähigkeiten sind nutzlos, wenn man jeden Tag hart arbeitet, anstatt in einem Schritt den Himmel zu erreichen. Eines Tages wird jeder Tropfen Wasser in den Stein eindringen. Es wird dunkel sein und die Blumen werden hell sein.
Mein Zweck
Weil ich in meinem zukünftigen Studium möglicherweise Netzwerkinhalte verwende, aber gleichzeitig haben viele Programmierer, die PHP schreiben, noch nie ein Sockets-Programm geschrieben, aber Ich muss davon gehört haben, und ich muss vom Wort Netzwerkprogrammierung gehört haben, daher habe ich vor, das relevante Wissen hier kurz zu erläutern. Dieser Blog-Beitrag enthält ein Beispielprogramm, und der Code wird auf Code Cloud gehostet (php-socket-base-code: https://gitee.com/obamajs/php-socket-base-code), Sie müssen es nur herunterladen, die entsprechende Umgebung konfigurieren und den Anweisungen zum Ausführen folgen.
Umgebungskonfiguration
Socket-Programmierung muss die Socket-Erweiterung von PHP aktivieren, daher müssen Sie hier nur die Datei php.ini öffnen und finden Sie diese Zeile. Entfernen Sie einfach die Kommentare
extension=sockets
Offizielles Dokument
Die offizielle Adresse der PHP-Socket-Programmierung lautet: PHP-Socket (https://www.php.net /manual/ en/book.sockets.php)
Serverseitige Programmierung
Die Socket-Programmierung erfolgt nach bestimmten Programmierschritten anders, schauen wir uns zuerst den Server an.
Socket erstellen
Sockets sind Systemressourcen. Wir rufen zunächst die Methode socket_create auf (siehe offizielle Dokumentation: https: / /www.php.net/manual/en/function.socket-create.php), der Aufruf lautet wie folgt:
$this->socket_handle = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if (!$this->socket_handle) { //创建失败抛出异常,socket_last_error获取最后一次socket操作错误码,socket_strerror打印出对应错误码所对应的可读性描述 throw new Exception(socket_strerror(socket_last_error($this->socket_handle))); } else { echo "create socket successful\n"; }
Der erste Parameter gibt an, ob der aktuelle Socket IPv4 oder IPv6 verwendet, wenn ja. Wenn ja Ersteres ist der Fall, dann übergeben Sie AF_INET, andernfalls gibt es natürlich einen anderen Typ, nämlich AF_UNIX. Dies wird im Allgemeinen nicht besprochen (IPv6 ist nicht sehr beliebt).
Der zweite Parameter gibt den Protokolltyp an. Im Allgemeinen ist TCP oder UDP eine zuverlässige Streaming-Übertragung (die am weitesten verbreitete im Leben, die Zuverlässigkeit und Sicherheit gewährleistet), während dies bei UDP nicht der Fall ist Wählt im Allgemeinen TCP aus.
Der dritte ist SOL_TCP, wenn Sie zuvor TCP ausgewählt haben, andernfalls ist es SOL_UDP.
Bindeadresse und Portnummer
Da ein Host möglicherweise mehrere IP-Adressen hat, müssen Sie angeben, auf welche Ihr Socket lauscht. Der häufig verwendete Wert ist 127,0 .0.1 oder alle Adressen abhören 0.0.0.0 Also versteht jemand hier möglicherweise nicht, was der Unterschied zwischen 127.0.0.1 und 0.0.0.0 ist. 127.0.0.1 ist nur eine Loopback-Adresse und kann nur für den lokalen Zugriff verwendet werden. Da diese IP nicht für die Außenwelt offen ist, kann niemand auf diese Adresse zugreifen, wenn Ihr Server Adresse ist auf 127.0.0 eingestellt, wenn andere zugreifen wollen, können sie nur scheiße gehen.
0.0.0.0 ist nicht unbedingt eine IP-Adresse. Das bedeutet, dass alle IP-Adressen dieser Maschine mir gehören, haha.
Das Obige verstanden, schauen wir uns den Aufrufcode an
if (!socket_bind($this->socket_handle, $this->addr, $this->port)) { throw new Exception(socket_strerror(socket_last_error($this->socket_handle))); } else { echo "bind addr successful\n"; }
Ist es sehr einfach? Der erste Parameter ist das von socket_create zurückgegebene Ergebnis und der zweite Parameter ist die Adresse Wie bereits erwähnt, ist der dritte Parameter die Portnummer.
Listening-Socket
Nach den obigen Schritten haben wir einfach einen Socket erstellt und die Portnummer und Adresse daran gebunden, aber was ist mit dem System? eine Hörsteckdose? Unsere Arbeit ist also noch nicht getan, also müssen wir es erzählen. Sagen Sie mir nicht, dass Sie in einer guten Beziehung zum System stehen! ! !
if (!socket_listen($this->socket_handle, $this->back_log)) { throw new Exception(socket_strerror(socket_last_error($this->socket_handle))); } else { echo "socket listen successful\n"; }
Der zweite Parameter ist es wert, mir im Detail zuzuhören. Für jeden Prozess im Linux-System verwaltet das System eine Warteschlange ausstehender Sockets (First In, First Out). Es gilt das Prinzip „Wer zuerst kommt, mahlt zuerst“). Es dauert einige Zeit, bis das übergeordnete Programm die Geschäftslogik verarbeitet. Warten Sie also einfach. Auf welche Größe ist diese Warteschlange eingestellt? Sein Wert ist der zweite Parameter. Kann ich ihn also auf einen großen Wert einstellen? Saonian, denkst du zu viel nach? Dieser Wert ist in verschiedenen Systemen unterschiedlich. Sagen Sie nicht, dass ich Sie täusche.
The maximum number passed to the backlog parameter highly depends on the underlying platform. On Linux, it is silently truncated to SOMAXCONN. On win32, if passed SOMAXCONN, the underlying service provider responsible for the socket will set the backlog to a maximum reasonable value. There is no standard provision to find out the actual backlog value on this platform.
Sie müssen sich nicht um die genauen Daten dieses Werts kümmern, sie sind bedeutungslos.
Alles ist bereit, alles was wir brauchen ist der Ostwind
Nach dem oben genannten Vorgang können wir beginnen, Verbindungen vom Client zu akzeptieren, und diese Funktion ist noch einfacher
$client_socket_handle = socket_accept($this->socket_handle);
Der Rückgabewert dieser Funktion ist auch ein Socket-Handle, sodass Sie ihn lesen und schreiben können. Im aktuellen Beispielprogramm ist das, was wir tun, sehr einfach, so einfach, dass Sie an Ihrem Leben zweifeln können.
$client_socket_handle = socket_accept($this->socket_handle); if (!$client_socket_handle) { echo "socket_accept call failed\n"; exit(1); } else { while (true) { $bytes_num = socket_recv($client_socket_handle, $buffer, 100, 0); if (!$bytes_num) { echo "socket_recv failed\n"; exit(1); } else { echo "content from client:" . $buffer . "\n"; } } }
Socket lesen
Am Beispiel des obigen Beispiels verwenden wir socket_recv, um den Inhalt vom Client zu lesen. Der Funktionsprototyp ist wie folgt
socket_recv ( resource $socket , string &$buf , int $len , int $flags ) : int
Der gelesene Inhalt wird im zweiten Parameter zurückgegeben. Der zweite Parameter übergibt die Anzahl der Zeichen, die wir lesen möchten. Der vierte Parameter kann direkt auf 0 gesetzt werden. Der Rückgabewert dieser Funktion ist der tatsächlich gelesene Wert. Die Anzahl der genommenen Bytes.
Client-Programmierung
客户端相对于服务端来说,就很简单了,流程如下
创建套接字前面已经讲过了,不再详述,客户端只需要连接服务器即可,函数为 socket_create,我们来看一哈在当前的例子中,我们是如何调用的。
if (!socket_connect($this->socket_handle, $this->server_addr, $this->server_port)) { echo socket_strerror(socket_last_error($this->socket_handle)) . "\n"; exit(1); } else { while (true) { $data = fgets(STDIN); //如果用户输入quit,那么退出程序 if (strcmp($data, "quit") == 0) { break; } socket_write($this->socket_handle, $data); } }
该函数只需要指定服务器的地址和端口号即可,参数是不是很简单
练习实例
在讲解基本函数调用的时候,我就把自带程序的核心部分,复制出来了,如果要完整的程序,这里是地址(php-socket-base-code:https://gitee.com/obamajs/php-socket-base-code),代码非常简单,再次提醒,这些代码完全是用于给大家讲解基本的 socket 变成操作,为大家以后的学习打下基础,那么如何使用这个例子程序呢?
进入到命令行,开启服务器程序
php TcpServer.php,
打开另外一个命令行界面,
php TcpClient.php,
在客户端界面,输入任何文本,再输入回车,再切换到服务器界面,您将会看到客户端输入的内容
在笔者的电脑上操作实例截图如下:
Das obige ist der detaillierte Inhalt vonSchreiben Sie grundlegende Socket-Programme in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!