Skip to content

Instantly share code, notes, and snippets.

@jerry80409
Created June 9, 2015 08:11
Show Gist options
  • Save jerry80409/cc9f12fda32496f44e22 to your computer and use it in GitHub Desktop.
Save jerry80409/cc9f12fda32496f44e22 to your computer and use it in GitHub Desktop.

Revisions

  1. jerry80409 created this gist Jun 9, 2015.
    140 changes: 140 additions & 0 deletions socket_server.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,140 @@
    <?php

    #error_reporting(E_ALL); // 顯示 所有的錯誤、警告
    set_time_limit(0); //最大執行時間:無限制
    ob_implicit_flush(); //立即清空
    socket_clear_error();



    /*******************************************************************************
    * Create Socket
    *******************************************************************************/

    $commonProtocol = getprotobyname("tcp");
    $resource = socket_create(AF_INET, SOCK_STREAM, $commonProtocol)
    OR die('Socket_Create - '.socket_strerror(socket_last_error()).PHP_EOL);

    # socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);

    socket_bind($resource, '127.0.0.1', 10001)
    OR die('Socket_Bind - '.socket_strerror(socket_last_error()) .PHP_EOL);

    // 5 - backlog指定同時能處理的最大連接要求,如果連接數目達此上限則client端將收到ECONNREFUSED的錯誤。
    // echo SOMAXCONN; 128
    socket_listen($resource, 5)
    OR die('Socket_Listen - '.socket_strerror(socket_last_error()) .PHP_EOL);

    /*******************************************************************************
    * Accept any incoming connections to the server
    *******************************************************************************/

    echo '---------- Waitting For Clients ---------- ' .PHP_EOL;

    //客戶端陣列
    $clients = array($resource);

    while (TRUE) {

    // 阻塞模式
    socket_set_block($resource);

    // 建立副本
    $read = $clients;

    // 避免線程卡住, 等待 20 秒後逾時,
    // socket_select - $read有動作或Timeout時會觸發一次執行

    if(socket_select($read, $write=NULL, $except=NULL, 20) < 1){

    // get a list of all the clients that have data to be read from
    // if there are no clients with data, go to next iteration
    echo 'Problem blocking socket_select?' .PHP_EOL;
    continue;
    }

    // 確認 $resource 是否於 $read 陣列中
    if(in_array($resource, $read)){

    // 若 $resource 有接收到訊息, 回傳新的 socket resource, 並新增到 $clients 陣列中
    // If socket has been made non-blocking using socket_set_blocking() or socket_set_nonblock(), FALSE will be returned.
    $new_socket = socket_accept($resource);
    $clients[] = $new_socket;

    var_dump($clients); // debug

    // timestamp
    echo date("Y-m-d H:i:s") .PHP_EOL;

    // welcome message
    socket_write($new_socket, 'Welcome ! There are ' .(count($clients)-1) .' clients in the server ! '.PHP_EOL );

    // get client ip
    socket_getpeername($new_socket, $remote_ip);
    echo 'Receive From - ' .$remote_ip .PHP_EOL;

    }





    foreach ($read as $read_sock) {

    var_dump($read_sock); // debug

    // read until newline or 1024 bytes
    $data = @socket_read($read_sock, 1024);

    // 收不到資料, 判斷為斷線
    if($data == NULL){

    // 若要設計成聊天室, 這邊需要緩衝 buffer

    // remove client for $clients array
    #$key = array_search($read_sock, $clients);
    #unset($read[$key]);
    #echo 'Client disconnected ! ' .PHP_EOL;

    echo 'No Data' .PHP_EOL;
    continue;
    }



    // blocking warring message
    @socket_getpeername($read_socket, $remote_ip);
    $data = trim($data);
    echo 'Receive Data ( ' .$remote_ip .' ) - ' .$data .PHP_EOL;

    // parser data

    // insert database

    /* //broadcast
    if(! empty($data)) {
    // send this to all the clients in the $clients array (except the first one, which is a listening socket)
    foreach ($clients as $send_sock) {
    if ($send_sock == $socket || $send_sock == $read_sock) {
    // if its the listening sock or the client that we got the message from, go to the next one in the list
    continue;
    }
    echo 'Receive Data - '.$data .PHP_EOL;
    socket_write($send_sock, $data .PHP_EOL);
    }
    }*/

    }

    // 若有需要, 可以設計條件跳出while
    // break;

    } // end while loop


    // close socket
    socket_close($socket);