Socketでechoサーバ,クライアント
Socketを使つかってみるためのメモ
とりあえずechoサーバ書くよね
- 複数のコネクションを受け付けるechoサーバ
- メッセージは他の接続者には送信しない(サーバとクライアントの1対1)
- "quit"を受けると接続を終了
- "shutdown"を受け取るとサーバを終了
サーバはこんな感じ
<?php error_reporting(E_ALL); //Allow the script to hang set_time_limit(0); //enables flush ob_implicit_flush(); $address = '192.168.0.1'; //addr $port = 10000; //port $backlog = 5; $bufsize = 2048; //socket:create→bind→listen if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false){ echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; } if (socket_bind($sock, $address, $port) === false){ echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } if (socket_listen($sock, $backlog) === false){ echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } //nonblockmode if(socket_set_nonblock($sock) === false){ echo "socket_set_nonblock() failed: reason: ". socket_strerror(socket_last_error($sock)). "\n"; } //clients list $clients = array($sock); //for select $read_sockets = array(); $write_sockets = NULL; $error_sockets = NULL; $select_interval = 0; //second while(true){ $read_sockets = $clients; //read only $select = socket_select($read_sockets, $write_sockets, $error_sockets, $select_interval); //new client or new message if($select >= 1){ //new client if(in_array($sock, $read_sockets)){ //add client $clients[] = $newsock = socket_accept($sock); //delete new client from read list $clients_key = array_search ($sock, $read_sockets); unset($read_sockets[$clients_key]); } //read message foreach($read_sockets as $read_key => $read_socket){ //reaf failed if(($read_buf = socket_read($read_socket, $bufsize, PHP_NORMAL_READ)) === false){ echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($read_socket)) . "\n"; //delete client $clients_key = array_search($read_socket, $clients); unset($read_sockets[$read_key]); unset($clients[$clients_key]); } //invalied message else if (!$read_buf = trim($read_buf)){ //delete client $clients_key = array_search($read_socket, $clients); unset($read_sockets[$read_key]); unset($clients[$clients_key]); continue; } echo $read_buf."\n"; //end of connection if ($read_buf == 'quit'){ $clients_key = array_search($read_socket, $clients); unset($read_sockets[$read_key]); unset($clients[$clients_key]); } //shutdown server else if ($read_buf == 'shutdown'){ //delete all client foreach($clients as $clients_key => $client){ if($sock != $client){ unset($client); } } break 2; } //echo back else{ //write message $write_buf = $read_buf."\n"; if(socket_write($read_socket, $write_buf, strlen($write_buf)) === false){ echo "socket_write() failed: rason: " . socket_strerror(socket_last_error($read_sock)); $clients_key = array_search($read_socket, $clients); unset($read_sockets[$read_key]); unset($clients[$clients_key]); } } } } //There is no readable socket else if($select == 0){ continue; } //select error else if($select === false){ echo "socket_select() failed: reason: ". sockets_strerror(socket_last_error($read_sock)) . "\n"; break; } } //close socket socket_close($sock); ?>
クライアントはこちら
<?php $test_servaddr = '192.168.0.1'; //server address $test_servport = 10000; //port //socket:create→connect if(($test_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false){ echo "socket_create() error:". socket_strerror(socket_last_error()); } if((socket_connect($test_sock, $test_servaddr, $test_servport)) === false){ echo "socket_connect() error:".socket_strerror(socket_last_error()); } while($test_inputbuf = fgets(STDIN,2048)){ if(!($test_inputbuf = trim($test_inputbuf))){ continue; } //output and create message echo "write:".$test_inputbuf."\n"; $test_writebuf = $test_inputbuf."\n"; //write message if(socket_write($test_sock, $test_writebuf, strlen($test_writebuf)) === false){ echo "socket_write() error:".socket_strerror(socket_last_error()); } //end of connection switch($test_inputbuf) { case 'quit': socket_close($test_sock); break 2; case 'shutdown': socket_close($test_sock); break 2; default : break; } //read and output message if(($test_readbuf = socket_read($test_sock, 2048, PHP_NORMAL_READ)) === false){ echo "socket_read() error:". socket_strerror(socket_last_error()); } else{ echo "read:".$test_readbuf; } } ?>
Cとかとほとんど変わりません。