ホームページ バックエンド開発 PHPチュートリアル PHPソケット通信デモとソケット操作クラス

PHPソケット通信デモとソケット操作クラス

Jun 23, 2016 pm 01:06 PM

Java コースの設計とアドレス帳を行う準備をします。 C/Sアーキテクチャを採用。クライアントはJava FXとJavaを使用し、サーバーはphpを使用し、ソケット通信を使用します。

PHP でのソケット通信について話しましょう:

その前に、TCP/IP と UDP について話さなければなりません。インターネットの普及に伴い、多かれ少なかれこれらのプロトコルについて聞いたことがある人は多いと思いますが、具体的にはどのようなものなのでしょうか?

1. TCP/IP、UDPとは何ですか?

TCP/IP (伝送制御プロトコル/インターネット プロトコル) は、ワイド エリア ネットワーク (WAN) 用に設計された業界標準のプロトコル セットです。 TCP/IP プロトコル スイートには、トランスポート層、ネットワーク層、およびリンク層が含まれます。
UDP (User Data Protocol) は、TCP に相当するプロトコルです。これは、TCP/IP プロトコル スイートのメンバーです。図 上 上でそれらの関係を直観的に示してみましょう:

ここではソケットではありません、ソケットはどこですか?使用は何ですか?心配しないでください。次にソケットとそれらの関係を紹介しましょう。上と同じ写真です。

これで二人の関係が分かりました。では、ソケットとは一体何でしょうか?使用は何ですか?

2. ソケットとは何ですか?用途は何ですか?

ソケットは、アプリケーション層と TCP/IP プロトコルスイート間の通信のための中間ソフトウェア抽象化層です。 インターフェイスのセットです。デザイン モードでは、Socket は実際にはファサード モードであり、複雑な TCP/IP プロトコル ファミリを Socket インターフェイスの背後に隠し、ユーザーにとっては一連の単純なインターフェイスだけで済み、Socket は指定されたプロトコルに準拠するようにデータを編成できます。

ソケットはカプセル化されたインターフェイスのセットであるため、それを使用して通信するにはどうすればよいでしょうか?具体的なプロセスは何ですか?電話のプロセスを詳しく説明します。まず第一に、私たちの通話は監視されなければなりませんね?そうでなければ、他の人から電話を受けることは絶対にありません。誰かが電話をかけてきたら、最初にその番号をダイヤルします。その番号がターゲットであり、唯一の番号です。ダイヤル後、電話が接続され、チャットが終了したら電話を切って、他の人がその番号に再度電話をかける必要があります。ソケットについても同様です。クライアントがソケットを作成して接続要求を開始すると、サーバーはまずソケットを確立し、情報の送信を開始します。送信が完了したらソケットを閉じます。もちろん、サーバーはクライアントへの接続要求をアクティブに開始して、通信を開始することもできます。これは、双方向通信を可能にする ajax とは異なります。下の写真を見てください:

サーバー側から始めましょう。サーバーはまずソケットを初期化し、次にポートにバインドし、ポートをリッスンし、accept を呼び出してブロックし、クライアントが接続するのを待ちます。このとき、クライアントがSocketを初期化してからサーバーに接続すると、接続に成功するとクライアントとサーバー間の接続が確立されます。クライアントがデータリクエストを送信し、サーバーがリクエストを受信して​​処理し、その後、応答データをクライアントに送信し、クライアントがデータを読み取り、最後に接続を終了します

3. 関連関数ソケットの:

socket_accept() はソケット接続を受け入れます
socket_bind() はソケットを IP アドレスとポートにバインドします
socket_clear_error() はソケットエラーまたは最後のエラーコードをクリアします
socket_close() はソケットリソースを閉じます
socket_connect() は 1 つのソケット接続を開始します

socket_create_listen() は、指定されたポートでリッスンするソケットを開きます
socket_create_pair() は、未分化のソケットのペアを配列に生成します
socket_create() は、ソケットを生成します。これは、ソケットのデータ構造を生成するのと同等です
socket_get_option() は、ソケットのオプションを取得します
socket_getpeername() リモートの同様のホストの IP アドレスを取得します
socket_getsockname() ローカル ソケットの IP アドレスを取得します
socket_iovec_add() 新しいベクトルを分散/集約配列に追加します
socket_iovec_alloc() この関数は、送信、受信、およびread iovec データ構造を書き込む
socket_iovec_delete() 割り当てられた iovec を削除する
socket_iovec_fetch() 指定された iovec リソースのデータを返す
socket_iovec_free() iovec リソースを解放する
socket_iovec_set() iovec データの新しい値を設定する
socket_last_error () を入手してくださいcurrent ソケットの最後のエラー コードです
​​socket_listen() は、指定されたソケットからのすべての接続をリッスンします
socket_read() は、指定された長さのデータを読み取ります
socket_readv() は、分散/集約配列からデータを読み取ります
socket_recv() は、ソケットからキャッシュへのデータ
socket_recvfrom() 指定されたソケットからのデータを受け取ります。指定されていない場合、現在のソケットがデフォルトになります
socket_recvmsg() iovec からメッセージを受信します
socket_select() 複数選択
socket_send() この関数はデータを次の宛先に送信します接続されたソケット
socket_sendmsg () ソケットにメッセージを送信します
socket_sendto() 指定されたアドレスのソケットにメッセージを送信します
socket_set_block() ソケットをブロックモードに設定します
socket_set_nonblock() ソケットを非ブロックモードに設定します
socket_set_option() ソケット オプションを設定します
socket_shutdown() この関数を使用すると、読み取り、書き込み、または指定されたソケットを閉じることができます
socket_strerror() 指定されたエラー番号を持つ詳細なエラーを返します
socket_write() ソケット キャッシュにデータを書き込みます

socket_writev () データを分散/集約配列に書き込みます

4. ソケット通信のデモ:

//服务器端:<br /><?php//确保在连接客户端时不会超时set_time_limit(0);$ip = '127.0.0.1';$port = 1935;/* +------------------------------- *    @socket通信整个过程 +------------------------------- *    @socket_create *    @socket_bind *    @socket_listen *    @socket_accept *    @socket_read *    @socket_write *    @socket_close +-------------------------------- */if(($sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) < 0) {    echo "socket_create() 失败的原因是:".socket_strerror($sock)."\n";}if(($ret = socket_bind($sock,$ip,$port)) < 0) {    echo "socket_bind() 失败的原因是:".socket_strerror($ret)."\n";}if(($ret = socket_listen($sock,4)) < 0) {    echo "socket_listen() 失败的原因是:".socket_strerror($ret)."\n";}$count = 0;do {    if (($msgsock = socket_accept($sock)) < 0) {        echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";        break;    } else {                //发到客户端        $msg ="测试成功!\n";        socket_write($msgsock, $msg, strlen($msg));                echo "测试成功了啊\n";        $buf = socket_read($msgsock,8192);                        $talkback = "收到的信息:$buf\n";        echo $talkback;                if(++$count >= 5){            break;        };                }    socket_close($msgsock);} while (true);socket_close($sock);?>
ログイン後にコピー

//客户端<br /><?phperror_reporting(E_ALL);set_time_limit(0);$ip = "127.0.0.1";$port = 1935;/* +------------------------------- *    @socket连接整个过程 +------------------------------- *    @socket_create *    @socket_connect *    @socket_write *    @socket_read *    @socket_close +-------------------------------- */$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);if ($socket < 0) {    echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";}else {    echo "OK.\n";}echo "试图连接 '$ip' 端口 '$port'...\n";$result = socket_connect($socket, $ip, $port);if ($result < 0) {    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";}else {    echo "连接OK\n";}$in = "Ho\r\n";$in .= "first blood\r\n";$out = '';if(!socket_write($socket, $in, strlen($in))) {    echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n";}else {    echo "发送到服务器信息成功!\n";    echo "发送的内容为:<font color='red'>$in</font> <br>";}while($out = socket_read($socket, 8192)) {    echo "接收服务器回传信息成功!\n";    echo "接受的内容为:",$out;}echo "关闭SOCKET...\n";socket_close($socket);echo "关闭OK\n";?>
ログイン後にコピー

注: 1) サーバーは CLI モード、つまりコマンドで実行する必要があります。ラインモード。 CGI (ブラウザ アクセス) を使用しないでください。php.exe が存在するディレクトリを見つけて、次のコード、PHP サーバー ファイルを実行します。

5. ソケットをクラスにカプセル化します:

//ServerSocket.class.php<br />//客户端socket操作类
ログイン後にコピー
<?php   error_reporting(E_ALL);   set_time_limit(0);      class ServerSocket {        private $server_host;  //服务器IP     private $server_port;  //服务器端口     private $client_host;  //客户端IP     private $client_port;  //客户端端口     private $create_socket=null;        private $accept_socket=null;     private $get_data="";     private $send_data="";              //够造函数     public function __construct($host,$port){         if(!extension_loaded("socket")){             exit("请先打开socket扩展!");         }         if(empty($host))              exit("请输入目标主机IP!");         if(empty($port))             exit("请输入有效端口号!");         $this->server_host=$host;         $this->server_port=$port;         $this->CreateSocket();     }          //创建一个socket并将其用来绑定监听端口     private function createSocket(){           if($this->create_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)==false){                 echo "socket_create() failed. reason:".socket_strerror(socket_last_error())."\n";           }           if(socket_bind($this->create_socket,$this->server_host,$this->server_port)==false){               echo "socket_bind()failed. reason:".socket_strerror(socket_last_error($this->create_socket))."\n";           }           if(socket_listen($this->create_socket,5)==false){               echo "socket_listen()failed. reason:".socket_strerror(socket_last_error($this->create_socket))."\n";           }             }          //向目标主机发起连接     public function connectClient(){         if(socket_getpeername($this->create_socket,$this->client_host,$this->client_port)==null){             echo "socket_getpeername()failed. reason:".socket_strerror(socket_last_error($this->create_socket))."\n";         }         if(socket_connect($this->create_socket,$this->client_host,$this->client_port)==false){             echo "socket_connect()failed. reason:".socket_strerror(socket_last_error($this->create_socket))."\n";         }     }     //接受连接获取到一个socket资源,想客户端读取以及传输信息     public function wr(){         do{   //循环防止阻塞延迟             if($this->accept_socket=socket_accept($this->create_socket)==null){                 echo "socket_accept()failed. reason:".socket_strerror(socket_last_error($this->create_socket))."\n";                 break;             }                          $this->get_data = socket_read($this->accept_socket, 8192);             $this->send_data=$this->operateData($this->get_data);             if (socket_write($this->accept_socket,$this->send_data, strlen($this->send_data))==false) {                 echo "socket_write() failed reason:" . socket_strerror(socket_last_error($this->accept_socket)) ."\n";             }             socket_close($this->accept_socket);         }while(true);               }          //数据处理     private function operateData(){                  return ;     }          //关闭监听socket     private function closeSocket(){         socket_close($this->createSocket);     }          //析构函数     public function  __destruct(){          $this->closeSocket();     }   }        
ログイン後にコピー

//ClientSocket.class.php//客户端socke操作类class Socket {    private $host;//连接socket的主机    private $port;//socket的端口号     private $error=array();    private $socket=null;//socket的连接标识    private $queryStr="";//发送的数据    public function __construct($host,$port) {        if(!extension_loaded("sockets")){            exit("请打开socket扩展 ");        }        if(empty($host)) exit("请输入目标地址");        if(empty($port)) exit("请输入有效的端口号");        $this->host=$host;        $this->port=$port;        $this->CreateSocket();//创建连接            }    //创建socket    private function CreateSocket(){        !$this->socket&&$this->socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP);//创建socket        $r=@socket_connect($this->socket,$this->host,$this->port);        if($r){            return $r;        }else{            $this->error[]=socket_last_error($this->socket);            return false;        }    }    //向socket服务器写入数据并读取    public function wr($contents){        $this->queryStr="";        $this->queryStr=$contents;        !$this->socket&&$this->CreateSocket();        $contents=$this->fliterSendData($contents);        $result=socket_write($this->socket,$contents,strlen($contents));        if(!intval($result)){            $this->error[]=socket_last_error($this->socket);            return false;        }        $response=socket_read($this->socket,12048);        if(false===$response){            $this->error[]=socket_last_error($this->socket);            return false;        }        return $response;    }    //对发送的数据进行过滤    private function fliterSendData($contents){        //对写入的数据进行处理        return $contents;    }    //所有错误信息     public function getError(){        return $this->error;    }    //最后一次错误信息    public function getLastError(){        return $this->error(count($this->error));    }        //获取最后一次发送的消息    public function getLastMsg(){        return $this->queryStr;    }    public function getHost(){        return $this->host;    }    public function getPort(){        return $this->port;    }    //关闭socket连接    private function close(){        $this->socket&&socket_close($this->socket);//关闭连接        $this->socket=null;//连接资源初始化    }    public function __destruct(){        $this->close();    }}
ログイン後にコピー

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

セッションのハイジャックはどのように機能し、どのようにPHPでそれを軽減できますか? セッションのハイジャックはどのように機能し、どのようにPHPでそれを軽減できますか? Apr 06, 2025 am 12:02 AM

セッションハイジャックは、次の手順で達成できます。1。セッションIDを取得します。2。セッションIDを使用します。3。セッションをアクティブに保ちます。 PHPでのセッションハイジャックを防ぐための方法には次のものが含まれます。1。セッション_regenerate_id()関数を使用して、セッションIDを再生します。2。データベースを介してストアセッションデータを3。

確固たる原則と、それらがPHP開発にどのように適用されるかを説明してください。 確固たる原則と、それらがPHP開発にどのように適用されるかを説明してください。 Apr 03, 2025 am 12:04 AM

PHP開発における固体原理の適用には、次のものが含まれます。1。単一責任原則(SRP):各クラスは1つの機能のみを担当します。 2。オープンおよびクローズ原理(OCP):変更は、変更ではなく拡張によって達成されます。 3。Lischの代替原則(LSP):サブクラスは、プログラムの精度に影響を与えることなく、基本クラスを置き換えることができます。 4。インターフェイス分離原理(ISP):依存関係や未使用の方法を避けるために、細粒インターフェイスを使用します。 5。依存関係の反転原理(DIP):高レベルのモジュールと低レベルのモジュールは抽象化に依存し、依存関係噴射を通じて実装されます。

システムの再起動後にUnixSocketの権限を自動的に設定する方法は? システムの再起動後にUnixSocketの権限を自動的に設定する方法は? Mar 31, 2025 pm 11:54 PM

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

phpstormでCLIモードをデバッグする方法は? phpstormでCLIモードをデバッグする方法は? Apr 01, 2025 pm 02:57 PM

phpstormでCLIモードをデバッグする方法は? PHPStormで開発するときは、PHPをコマンドラインインターフェイス(CLI)モードでデバッグする必要がある場合があります。

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPのCurlライブラリを使用してJSONデータを含むPOSTリクエストを送信する方法は? PHPのCurlライブラリを使用してJSONデータを含むPOSTリクエストを送信する方法は? Apr 01, 2025 pm 03:12 PM

PHP開発でPHPのCurlライブラリを使用してJSONデータを送信すると、外部APIと対話する必要があることがよくあります。一般的な方法の1つは、Curlライブラリを使用して投稿を送信することです。

See all articles