2012-10-24 2 views
10

GPRS 연결을 통해 정의 된 공개 서버 : 포트에 데이터를 연결하고 전송하는 GPS 트래커가 있습니다. 나는 IP를 정의 할 수 있습니다 PHP를 사용하여 TCP 포트를 수신하는 방법은 무엇입니까?

: GPS 장치의 포트

내 질문에 난 그냥 내 서버에 포트를 열고 듣기/PHP를 이용하여 수신 데이터를 저장할 수있다

?

감사합니다. socket_create, socket_bind, socket_listen하고있다

http://www.php.net/manual/en/function.socket-create.php

http://www.php.net/manual/en/function.socket-bind.php

http://www.php.net/manual/en/function.socket-listen.php

http://www.php.net/manual/en/function.socket-accept.php

socket_accept을 사용

+1

http://php.net/manual/en/function.socket-listen.php? –

+0

GPS 추적기의 제작자 및 모델은 무엇입니까 ?? 대부분 나는 또한 HTTP GET을 지원합니다. – Baba

+0

그냥 시도해 보는 것에서 당신을 방해합니까? 어떤 구체적인 오류가 발생합니까? – hakre

답변

8

편집/업데이트 2017년 8월 16일 : 사용자 및 라이브러리 저자 < @Navarr는> 그가 내 원래의 대답에 코드에서 기반 된 라이브러리의 새로운 업데이트 버전을 출시했습니다 댓글을 달았습니다. new code on his github here에 대한 링크. 새 코드를 자유롭게 탐색하고 통찰력을 얻기 위해 원래 예제를 다시 참조하십시오 (개인적으로 새로운 코드를 탐색/사용하지 않았습니다).


아래 코드는 여기에있는 SocketServer.class.php 파일을 사용합니다. 그것은 리눅스에서 필자가 파일을 실행 가능하도록 만든 다음 "php my_server.php"를 사용하여 명령 행에서 실행해야한다는 것을 의미하는 독립형 프로세스로 실행하기위한 것입니다. 명령 줄에서 실행되는 PHP 스크립트에 대한 자세한 내용은 : http://www.funphp.com/?p=33

먼저 잡고 SocketServer.class.php 현재 파일 : http://www.phpclasses.org/browse/file/31975.html

다음, 그것의 활용이 시도 수신 처리를 조정할 당신의 필요에 따라 들어오는 데이터를 소유하십시오. 희망이 도움이됩니다.

<?php 

require_once("SocketServer.class.php"); // Include the File 
$server = new SocketServer("192.168.1.6",31337); // Create a Server binding to the given ip address and listen to port 31337 for connections 
$server->max_clients = 10; // Allow no more than 10 people to connect at a time 
$server->hook("CONNECT","handle_connect"); // Run handle_connect every time someone connects 
$server->hook("INPUT","handle_input"); // Run handle_input whenever text is sent to the server 
$server->infinite_loop(); // Run Server Code Until Process is terminated. 


function handle_connect(&$server,&$client,$input) 
{ 
    SocketServer::socket_write_smart($client->socket,"String? ",""); 
} 
function handle_input(&$server,&$client,$input) 
{ 
    // You probably want to sanitize your inputs here 
    $trim = trim($input); // Trim the input, Remove Line Endings and Extra Whitespace. 

    if(strtolower($trim) == "quit") // User Wants to quit the server 
    { 
     SocketServer::socket_write_smart($client->socket,"Oh... Goodbye..."); // Give the user a sad goodbye message, meany! 
     $server->disconnect($client->server_clients_index); // Disconnect this client. 
     return; // Ends the function 
    } 

    $output = strrev($trim); // Reverse the String 

    SocketServer::socket_write_smart($client->socket,$output); // Send the Client back the String 
    SocketServer::socket_write_smart($client->socket,"String? ",""); // Request Another String 
} 

편집 :이 답변에 대한 적절하고 기능적인 물건을 유지 나는 그것을 가장 항상에서 제공되는 지정된 URL에서 (또는 가능한 상태로 유지하지 않을 수 있습니다 외부 소스 코드에 의존 계속하지 발견 내 링크). 따라서 편의상이 게시물의 맨 위에 링크 된 SocketServer.class.php 파일에 해당하는 코드를 아래에 추가합니다. (복사/붙여 넣기 중 들여 쓰기/서식 지정의 길이와 가능한 부족에 대한 사과, 나는 아래 코드의 작성자가 아닙니다.)

<?php 
    /*! @class SocketServer 
    @author Navarr Barnier 
    @abstract A Framework for creating a multi-client server using the PHP language. 
    */ 
    class SocketServer 
    { 
    /*! @var config 
    @abstract Array - an array of configuration information used by the server. 
    */ 
    protected $config; 

    /*! @var hooks 
    @abstract Array - a dictionary of hooks and the callbacks attached to them. 
    */ 
    protected $hooks; 

    /*! @var master_socket 
    @abstract resource - The master socket used by the server. 
    */ 
    protected $master_socket; 

    /*! @var max_clients 
    @abstract unsigned int - The maximum number of clients allowed to connect. 
    */ 
    public $max_clients = 10; 

    /*! @var max_read 
    @abstract unsigned int - The maximum number of bytes to read from a socket at a single time. 
    */ 
    public $max_read = 1024; 

    /*! @var clients 
    @abstract Array - an array of connected clients. 
    */ 
    public $clients; 

    /*! @function __construct 
    @abstract Creates the socket and starts listening to it. 
    @param string - IP Address to bind to, NULL for default. 
    @param int - Port to bind to 
    @result void 
    */ 
    public function __construct($bind_ip,$port) 
    { 
    set_time_limit(0); 
    $this->hooks = array(); 

    $this->config["ip"] = $bind_ip; 
    $this->config["port"] = $port; 

    $this->master_socket = socket_create(AF_INET, SOCK_STREAM, 0); 
    socket_bind($this->master_socket,$this->config["ip"],$this->config["port"]) or die("Issue Binding"); 
    socket_getsockname($this->master_socket,$bind_ip,$port); 
    socket_listen($this->master_socket); 
    SocketServer::debug("Listenting for connections on {$bind_ip}:{$port}"); 
    } 

    /*! @function hook 
    @abstract Adds a function to be called whenever a certain action happens. Can be extended in your implementation. 
    @param string - Command 
    @param callback- Function to Call. 
    @see unhook 
    @see trigger_hooks 
    @result void 
    */ 
    public function hook($command,$function) 
    { 
    $command = strtoupper($command); 
    if(!isset($this->hooks[$command])) { $this->hooks[$command] = array(); } 
    $k = array_search($function,$this->hooks[$command]); 
    if($k === FALSE) 
    { 
    $this->hooks[$command][] = $function; 
    } 
    } 

    /*! @function unhook 
    @abstract Deletes a function from the call list for a certain action. Can be extended in your implementation. 
    @param string - Command 
    @param callback- Function to Delete from Call List 
    @see hook 
    @see trigger_hooks 
    @result void 
    */ 
    public function unhook($command = NULL,$function) 
    { 
    $command = strtoupper($command); 
    if($command !== NULL) 
    { 
    $k = array_search($function,$this->hooks[$command]); 
    if($k !== FALSE) 
    { 
    unset($this->hooks[$command][$k]); 
    } 
    } else { 
    $k = array_search($this->user_funcs,$function); 
    if($k !== FALSE) 
    { 
    unset($this->user_funcs[$k]); 
    } 
    } 
    } 

    /*! @function loop_once 
    @abstract Runs the class's actions once. 
    @discussion Should only be used if you want to run additional checks during server operation. Otherwise, use infinite_loop() 
    @param void 
    @see infinite_loop 
    @result bool - True 
    */ 
    public function loop_once() 
    { 
    // Setup Clients Listen Socket For Reading 
    $read[0] = $this->master_socket; 
    for($i = 0; $i < $this->max_clients; $i++) 
    { 
    if(isset($this->clients[$i])) 
    { 
    $read[$i + 1] = $this->clients[$i]->socket; 
    } 
    } 

    // Set up a blocking call to socket_select 
    if(socket_select($read,$write = NULL, $except = NULL, $tv_sec = 5) < 1) 
    { 
    // SocketServer::debug("Problem blocking socket_select?"); 
    return true; 
    } 

    // Handle new Connections 
    if(in_array($this->master_socket, $read)) 
    { 
    for($i = 0; $i < $this->max_clients; $i++) 
    { 
    if(empty($this->clients[$i])) 
    { 
    $temp_sock = $this->master_socket; 
    $this->clients[$i] = new SocketServerClient($this->master_socket,$i); 
    $this->trigger_hooks("CONNECT",$this->clients[$i],""); 
    break; 
    } 
    elseif($i == ($this->max_clients-1)) 
    { 
    SocketServer::debug("Too many clients... :("); 
    } 
    } 

    } 

    // Handle Input 
    for($i = 0; $i < $this->max_clients; $i++) // for each client 
    { 
    if(isset($this->clients[$i])) 
    { 
    if(in_array($this->clients[$i]->socket, $read)) 
    { 
    $input = socket_read($this->clients[$i]->socket, $this->max_read); 
    if($input == null) 
    { 
    $this->disconnect($i); 
    } 
    else 
    { 
    SocketServer::debug("{$i}@{$this->clients[$i]->ip} --> {$input}"); 
    $this->trigger_hooks("INPUT",$this->clients[$i],$input); 
    } 
    } 
    } 
    } 
    return true; 
    } 

    /*! @function disconnect 
    @abstract Disconnects a client from the server. 
    @param int - Index of the client to disconnect. 
    @param string - Message to send to the hooks 
    @result void 
    */ 
    public function disconnect($client_index,$message = "") 
    { 
    $i = $client_index; 
    SocketServer::debug("Client {$i} from {$this->clients[$i]->ip} Disconnecting"); 
    $this->trigger_hooks("DISCONNECT",$this->clients[$i],$message); 
    $this->clients[$i]->destroy(); 
    unset($this->clients[$i]); 
    } 

    /*! @function trigger_hooks 
    @abstract Triggers Hooks for a certain command. 
    @param string - Command who's hooks you want to trigger. 
    @param object - The client who activated this command. 
    @param string - The input from the client, or a message to be sent to the hooks. 
    @result void 
    */ 
    public function trigger_hooks($command,&$client,$input) 
    { 
    if(isset($this->hooks[$command])) 
    { 
    foreach($this->hooks[$command] as $function) 
    { 
    SocketServer::debug("Triggering Hook '{$function}' for '{$command}'"); 
    $continue = call_user_func($function,$this,$client,$input); 
    if($continue === FALSE) { break; } 
    } 
    } 
    } 

    /*! @function infinite_loop 
    @abstract Runs the server code until the server is shut down. 
    @see loop_once 
    @param void 
    @result void 
    */ 
    public function infinite_loop() 
    { 
    $test = true; 
    do 
    { 
    $test = $this->loop_once(); 
    } 
    while($test); 
    } 

    /*! @function debug 
    @static 
    @abstract Outputs Text directly. 
    @discussion Yeah, should probably make a way to turn this off. 
    @param string - Text to Output 
    @result void 
    */ 
    public static function debug($text) 
    { 
    echo("{$text}\r\n"); 
    } 

    /*! @function socket_write_smart 
    @static 
    @abstract Writes data to the socket, including the length of the data, and ends it with a CRLF unless specified. 
    @discussion It is perfectly valid for socket_write_smart to return zero which means no bytes have been written. Be sure to use the === operator to check for FALSE in case of an error. 
    @param resource- Socket Instance 
    @param string - Data to write to the socket. 
    @param string - Data to end the line with. Specify a "" if you don't want a line end sent. 
    @result mixed - Returns the number of bytes successfully written to the socket or FALSE on failure. The error code can be retrieved with socket_last_error(). This code may be passed to socket_strerror() to get a textual explanation of the error. 
    */ 
    public static function socket_write_smart(&$sock,$string,$crlf = "\r\n") 
    { 
    SocketServer::debug("<-- {$string}"); 
    if($crlf) { $string = "{$string}{$crlf}"; } 
    return socket_write($sock,$string,strlen($string)); 
    } 

    /*! @function __get 
    @abstract Magic Method used for allowing the reading of protected variables. 
    @discussion You never need to use this method, simply calling $server->variable works because of this method's existence. 
    @param string - Variable to retrieve 
    @result mixed - Returns the reference to the variable called. 
    */ 
    function &__get($name) 
    { 
    return $this->{$name}; 
    } 
    } 

    /*! @class SocketServerClient 
    @author Navarr Barnier 
    @abstract A Client Instance for use with SocketServer 
    */ 
    class SocketServerClient 
    { 
    /*! @var socket 
    @abstract resource - The client's socket resource, for sending and receiving data with. 
    */ 
    protected $socket; 

    /*! @var ip 
    @abstract string - The client's IP address, as seen by the server. 
    */ 
    protected $ip; 

    /*! @var hostname 
    @abstract string - The client's hostname, as seen by the server. 
    @discussion This variable is only set after calling lookup_hostname, as hostname lookups can take up a decent amount of time. 
    @see lookup_hostname 
    */ 
    protected $hostname; 

    /*! @var server_clients_index 
    @abstract int - The index of this client in the SocketServer's client array. 
    */ 
    protected $server_clients_index; 

    /*! @function __construct 
    @param resource- The resource of the socket the client is connecting by, generally the master socket. 
    @param int - The Index in the Server's client array. 
    @result void 
    */ 
    public function __construct(&$socket,$i) 
    { 
    $this->server_clients_index = $i; 
    $this->socket = socket_accept($socket) or die("Failed to Accept"); 
    SocketServer::debug("New Client Connected"); 
    socket_getpeername($this->socket,$ip); 
    $this->ip = $ip; 
    } 

    /*! @function lookup_hostname 
    @abstract Searches for the user's hostname and stores the result to hostname. 
    @see hostname 
    @param void 
    @result string - The hostname on success or the IP address on failure. 
    */ 
    public function lookup_hostname() 
    { 
    $this->hostname = gethostbyaddr($this->ip); 
    return $this->hostname; 
    } 

    /*! @function destroy 
    @abstract Closes the socket. Thats pretty much it. 
    @param void 
    @result void 
    */ 
    public function destroy() 
    { 
    socket_close($this->socket); 
    } 

    function &__get($name) 
    { 
    return $this->{$name}; 
    } 

    function __isset($name) 
    { 
    return isset($this->{$name}); 
    } 
} 
+0

이 스크립트는 동일한 서버에서 실행되어야합니다. – gustyaquino

+0

예. 내 Linux 서버에서 실행했습니다. 이 스크립트를 "my_server.php"라는 파일에 넣고 SocketServer.class.php와 함께 자신의 폴더에 넣습니다. 해당 디렉토리로 이동하여 파일을 실행 가능하게 만들고 ("chmod a + x my_server.php") 명령 행에서 "php my_server.php"를 실행하십시오. –

+0

좋습니다. 시도했습니다. "주소를 바인드 할 수 없습니다. 주소는 이미 사용 중입니다."라는 오류 메시지가 표시됩니다. 이것은 무엇을 의미 하는가? – gustyaquino

9

네, 해당 페이지에서 사용 방법에 대한 예제가 많이 있습니다.

+1

서버에 수행 된 작업이 있습니까? 포트를 열어? – gustyaquino

+0

그래, 그걸 'socket_bind' 호출로 지정하십시오. – hexist

관련 문제