有3个用户通过socket登录到了服务端,通过mysql记录下了三个用户的IP与端口分别为:
A: 192.168.1.100:13564 B:192.168.1.100:13565 C:192.168.1.100:13566现在我想在客户A发一个指今(包含客户B的端口),服务端接受分析后从数据库取出客户B对应的地址发个TEST字符给B我在服务端加入如下代码,出现错误,
PHP Warning:  socket_connect(): unable to connect [0]: 提供了一个无效的参数。
$conn = socket_connect ($socket, '192.168.1.100', 13565);  
$buffer = "ok";
$command = socket_sendto($socket,$buffer,strlen($buffer),0,'192.168.1.100','192.168.1.100');
可以在服务端用socket_sendto吗?这个怎么实现啊?
 
服务端:$addr = "192.168.1.121";
$port = 1338;$remoteIP = "";
$remotePort = "";$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
if($socket < 0) {
        echo "Socket create:".$socket_strerror($socket)."\n";
        exit;
}
if ( ($ret = socket_bind($socket, $addr, $port)) < 0 ) {
    echo "socket bind:".socket_strerror()."\n";
    exit;
}
if ( ($ret = socket_listen($socket, 5)) < 0 ) {
    echo "socket listen:".socket_strerror()."\n";
    exit;
}socket_set_nonblock($socket);echo "Wainting for a connection:\n";$clients = array($socket);
while(true) {
    $read = $clients;
    if(socket_select($read, $writes=NULL, $execs=NULL, 3) < 1){
        //echo ".";
        continue;
    }    if(in_array($socket,$read)) {
        $clients[] = $newsock = socket_accept($socket);
        socket_set_nonblock($newsock);
        socket_getpeername($newsock,&$remoteIP,&$remotePort);        
        $key = array_search($socket,$read);
        unset($read[$key]);
        $msg = "Server: $addr\r\n".
                "Notice:Welcome the user from ".$remoteIP.":".$remotePort.".\r\n";
        echo $remoteIP.":".$remotePort." conected in.\r\n";
        socket_write($newsock,$msg);
    }    foreach($read as $read_sock) {
        $data = @socket_read($read_sock,1024,PHP_BINARY_READ);
        if($data == false) {
            $key = array_search($read_sock,$clients);
            print_r($clients[$key]);
            unset($clients[$key]);
            socket_close($read_sock);
            echo "Client disconnected.\n";
            continue;
        }
        
        $command = strtoupper ($data);
        
        switch ($command)
        {
            case "LIST":
                $writer = print_r($clients,1);
                break;
            case "HELLO":
                $writer = "Hello Everybody!";
                break;
            case "QUIT":
                $writer = "Bye-Bye";
                break;
            case "SLEEP":
                sleep(30);
                $writer = "sleeped 10 seconds!";
                break;
            case "HELP":
                $writer = "HELLO\tQUIT\tHELP";
                break;
            default:
                $writer = "Error Command!\r\nType help for help message!";
        }        socket_write($read_sock, $writer);
        //exit;
    }
}
socket_close($socket);
客户端:// Client  
 // 设置错误处理 
 error_reporting (E_ALL); 
 // 设置处理时间 
 set_time_limit (0); 
  
 $ip = "192.168.1.121";       // IP 地址 
 $port = 1338;            // 端口号 
  
 $socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);   // 创建一个SOCKET 
 if ($socket) 
     echo "socket_create() successed!\n"; 
 else 
     echo "socket_create() failed:".socket_strerror ($socket)."\n"; 
  
 $conn = socket_connect ($socket, $ip, $port);       // 建立SOCKET的连接 
 if ($conn) 
     echo "Success to connection![".$ip.":".$port."]\n"; 
 else 
     echo "socket_connect() failed:".socket_strerror ($conn)."\n"; 
  
 echo socket_read ($socket, 1024);    
  
 $stdin = fopen ('php://stdin', 'r'); 
 while (true) 
 { 
     $command = trim (fgets ($stdin, 1024)); 
     socket_write ($socket, $command, strlen ($command)); 
     $msg = trim (socket_read ($socket, 1024)); 
     echo $msg."\n"; 
     if ($msg == "Bye-Bye") 
         break; 
 } 
 fclose ($stdin); 
 socket_close ($socket);

解决方案 »

  1.   

    从C的角度来讲,1,因为有数据库阻塞操作,采用非异步架构使用多线程接入客户端即可,简单暴力。
    2,借助epoll+mysql线程池+状态机,做task dispatch-response的异步架构,高性能高扩展。从PHP的角度来讲,1,代码离底层太远了。
    2,线程不给力。
      

  2.   

    socket_sendto 端口号要写进去
      

  3.   

    代码如下,客户端发送指令过去,可以收到字符长度,但是提定的端口无法收到这个信息。是怎么回事啊。server.phpclass SocketAction extends Action {

    public function __construct(){
    parent::__construct(); 
    }

    public function _action(){
    $this->socket();
    }

    private function socket(){
    $remoteIP = "";
    $remotePort = "";

    $socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
    if ($socket < 0) {
            echo "Socket create:".socket_strerror($socket)."\n";
            exit;
    }
    if (($ret = socket_bind($socket, SOCKET_HOST, SOCKET_PORT)) < 0 ) {
        echo "socket bind:".socket_strerror()."\n";
        exit;
    }
    if (($ret = socket_listen($socket, 5)) < 0 ) {
        echo "socket listen:".socket_strerror()."\n";
        exit;
    }

    socket_set_nonblock($socket);

    echo "Wainting for a connection:\n";

    $clients = array($socket);

    while(true) {
        $read = $clients;
        if(socket_select($read, $writes=NULL, $execs=NULL, 3) < 1){
            //echo ".";
            continue;
         }

        if(in_array($socket,$read)) {
            $clients[] = $newsock = socket_accept($socket);
            socket_set_nonblock($newsock);
            socket_getpeername($newsock,$remoteIP,$remotePort);        
            $key = array_search($socket,$read);
            unset($read[$key]);
            $msg = "Server: ".SOCKET_HOST."\r\n".
                    "Notice:Welcome the user from ".$remoteIP.":".$remotePort.".\r\n";
            echo $remoteIP.":".$remotePort." conected in.\r\n";
            socket_write($newsock,$msg);
        }

        foreach($read as $read_sock) {
            $data = @socket_read($read_sock,1024,PHP_BINARY_READ);
            if($data == false) {
                $key = array_search($read_sock,$clients);
                print_r($clients[$key]);
                unset($clients[$key]);
                socket_close($read_sock);
                echo "Client disconnected.\n";
                continue;
            }
            //$data为对方传入的数据,1.接收对方数据 (经度,维度),2. 不返回任何值
            //$command = $this->handler($data);
            if($data){
             socket_getpeername($newsock,$remoteIP,$remotePort);          $data = 'connect,15950123153,189121321749';
    $data = explode(',',$data);
             switch ($data[0]){
             case 'connect':
             $command = $this->handlerConnect($data);
             break;
             }
            
            }
            socket_write($read_sock, $command);
        }
    }
    socket_close($socket);
    }

    private function handlerConnect($data){
    $_user = new UsersModel();
    $_user->mobile_number = $data[2];
    $object = $_user->showRemote();
    $sock = socket_create(AF_INET,SOCK_DGRAM,SOL_UDP);
    $msg = "Ping!aaaaa!";
    $len = strlen($msg);
    $int = socket_sendto($sock, $msg, $len, 0, $object->remote_ip, $object->remote_port);
        return $int;
    socket_close($sock);

    }
    }
    client.php// Client  
     // 设置错误处理 
     error_reporting (E_ALL); 
     // 设置处理时间 
     set_time_limit (0); 
      
     $ip = "192.168.1.121";       // IP 地址 
     $port = 1338;            // 端口号 
      
     $socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);   // 创建一个SOCKET 
     if ($socket) 
         echo "socket_create() successed!\n"; 
     else 
         echo "socket_create() failed:".socket_strerror ($socket)."\n"; 
      
     $conn = socket_connect ($socket, $ip, $port);       // 建立SOCKET的连接 
     if ($conn) 
         echo "Success to connection![".$ip.":".$port."]\n"; 
     else 
         echo "socket_connect() failed:".socket_strerror ($conn)."\n"; 
     
     echo socket_read ($socket, 1024);    
      
     $stdin = fopen ('php://stdin', 'r'); 
     while (true) 
     { 
         $command = trim (fgets ($stdin, 1024)); 
         socket_write ($socket, $command, strlen ($command)); 
         $msg = trim (socket_read ($socket, 1024)); 
         echo $msg."\n"; 
         if ($msg == "Bye-Bye") 
             break; 
     } 
     fclose ($stdin); 
     socket_close ($socket);
      

  4.   

    代码如下,客户端发送指令过去,可以收到字符长度,但是提定的端口无法收到这个信息。是怎么回事啊。server.phpclass SocketAction extends Action {

    public function __construct(){
    parent::__construct(); 
    }

    public function _action(){
    $this->socket();
    }

    private function socket(){
    $remoteIP = "";
    $remotePort = "";

    $socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
    if ($socket < 0) {
            echo "Socket create:".socket_strerror($socket)."\n";
            exit;
    }
    if (($ret = socket_bind($socket, SOCKET_HOST, SOCKET_PORT)) < 0 ) {
        echo "socket bind:".socket_strerror()."\n";
        exit;
    }
    if (($ret = socket_listen($socket, 5)) < 0 ) {
        echo "socket listen:".socket_strerror()."\n";
        exit;
    }

    socket_set_nonblock($socket);

    echo "Wainting for a connection:\n";

    $clients = array($socket);

    while(true) {
        $read = $clients;
        if(socket_select($read, $writes=NULL, $execs=NULL, 3) < 1){
            //echo ".";
            continue;
         }

        if(in_array($socket,$read)) {
            $clients[] = $newsock = socket_accept($socket);
            socket_set_nonblock($newsock);
            socket_getpeername($newsock,$remoteIP,$remotePort);        
            $key = array_search($socket,$read);
            unset($read[$key]);
            $msg = "Server: ".SOCKET_HOST."\r\n".
                    "Notice:Welcome the user from ".$remoteIP.":".$remotePort.".\r\n";
            echo $remoteIP.":".$remotePort." conected in.\r\n";
            socket_write($newsock,$msg);
        }

        foreach($read as $read_sock) {
            $data = @socket_read($read_sock,1024,PHP_BINARY_READ);
            if($data == false) {
                $key = array_search($read_sock,$clients);
                print_r($clients[$key]);
                unset($clients[$key]);
                socket_close($read_sock);
                echo "Client disconnected.\n";
                continue;
            }
            //$data为对方传入的数据,1.接收对方数据 (经度,维度),2. 不返回任何值
            //$command = $this->handler($data);
            if($data){
             socket_getpeername($newsock,$remoteIP,$remotePort);          $data = 'connect,15950123153,189121321749';
    $data = explode(',',$data);
             switch ($data[0]){
             case 'connect':
             $command = $this->handlerConnect($data);
             break;
             }
            
            }
            socket_write($read_sock, $command);
        }
    }
    socket_close($socket);
    }

    private function handlerConnect($data){
    $_user = new UsersModel();
    $_user->mobile_number = $data[2];
    $object = $_user->showRemote();
    $sock = socket_create(AF_INET,SOCK_DGRAM,SOL_UDP);
    $msg = "Ping!aaaaa!";
    $len = strlen($msg);
    $int = socket_sendto($sock, $msg, $len, 0, $object->remote_ip, $object->remote_port);
        return $int;
    socket_close($sock);

    }
    }
    client.php// Client  
     // 设置错误处理 
     error_reporting (E_ALL); 
     // 设置处理时间 
     set_time_limit (0); 
      
     $ip = "192.168.1.121";       // IP 地址 
     $port = 1338;            // 端口号 
      
     $socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);   // 创建一个SOCKET 
     if ($socket) 
         echo "socket_create() successed!\n"; 
     else 
         echo "socket_create() failed:".socket_strerror ($socket)."\n"; 
      
     $conn = socket_connect ($socket, $ip, $port);       // 建立SOCKET的连接 
     if ($conn) 
         echo "Success to connection![".$ip.":".$port."]\n"; 
     else 
         echo "socket_connect() failed:".socket_strerror ($conn)."\n"; 
     
     echo socket_read ($socket, 1024);    
      
     $stdin = fopen ('php://stdin', 'r'); 
     while (true) 
     { 
         $command = trim (fgets ($stdin, 1024)); 
         socket_write ($socket, $command, strlen ($command)); 
         $msg = trim (socket_read ($socket, 1024)); 
         echo $msg."\n"; 
         if ($msg == "Bye-Bye") 
             break; 
     } 
     fclose ($stdin); 
     socket_close ($socket);
      

  5.   

    PHP 没有线程。 所以,只能有1个 地址可以与 服务器进行通讯。 另外1个地址,不被服务器记录的状态下,是不可能说即时把 A 的信息发送到B 去。
    如果需要即时通讯,
    1)必须要有信息存入位置。2)客户端必须不停的与服务端进行连接。(但是就有问题了,因为A B C ...都不停地进行连接和中断连接,B 可能需要很长的一段时间才可以 返回到他需要的信息. 这样的话还不如直接刷新页面取数据库信息更好。还能减少服务器的消耗。)
      

  6.   

    代码是从网络是copy下来的,
    如下,如果客户端有输入,会返回一个空格,如果不想将msg的空格输出,该如何操作啊,我直接屏蔽会有错误,
    下面的代码请看懂的人帮忙解释一下,THSif(in_array($socket,$read)) {
            $clients[] = $newsock = socket_accept($socket);
            socket_set_nonblock($newsock);
            socket_getpeername($newsock,$remoteIP,$remotePort);        
            $key = array_search($socket,$read);
            unset($read[$key]);
            //$msg = "Server: ".SOCKET_HOST."\r\n".
            //        "Notice:Welcome the user from ".$remoteIP.":".$remotePort.".\r\n";
            $msg = ' ';
            //echo $remoteIP.":".$remotePort." conected in.\r\n";
            socket_write($newsock,$msg);
        }
      

  7.   

    http://blog.csdn.net/hguisu/article/details/7448528
     方法作用。 可以查看这篇文章。
      

  8.   

    http://blog.csdn.net/hguisu/article/details/7448528
    方法. 详见socket
      

  9.   

    http://blog.csdn.net/hguisu/article/details/7448528
     方法作用。 可以查看这篇文章。