【问题标题】:Why am I getting this error with socket_read()?为什么我在使用 socket_read() 时收到此错误?
【发布时间】:2011-04-11 18:01:14
【问题描述】:

我有以下代码:http://pastebin.com/U9qYSmET

当我尝试远程登录到我的服务器和端口时

telnet localhost 6667

我收到以下错误:

PHP 警告:socket_read():无法从套接字 [107] 读取:传输端点未连接在第 91 行的 /var/www/php-irc/proxy.php 中

有人知道为什么我会收到此错误吗?

代码:

<?php 

if(!defined('SOCKET_ADDRESS')) {
    define('SOCKET_ADDRESS', '127.0.0.1');
}

if(!defined('SOCKET_PORT')) {
    define('SOCKET_PORT', '6667');
}

if(!defined('MAX_CLIENTS')) {
    define('MAX_CLIENTS', '10');
}
set_time_limit(0);

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($socket, SOCKET_ADDRESS, SOCKET_PORT) or die('Could not bind to address ' . SOCKET_ADDRESS . ' on port ' . SOCKET_PORT . "!\n");
socket_listen($socket, MAX_CLIENTS) or die ("Could not setup socket listener!\n");

// setup read socket array
$read = array();

// client array w/ default initial socket
$clients = array('0' => array('socket' => $socket));

// force debug at first run..
$debug = true;
$time = time();
printf('Time: %d%s', $time, "\n");
while(true) {

    if(time() - $time >= 10) {
        $time = time();
        printf('Time: %d%s', $time, "\n");
        $debug = true;
    }
    if($debug === true) {
        printf('Debug: %s%s', $debug, "\n");
    }
    // $read[0] = $socket;
    if($debug) {
        var_dump($read);
    }

    // Handle clients
    for($i = 0; $i < count($clients); $i++) {
        if(isset($clients[$i]['socket'])) {
            if($debug === true) {
                printf('Setting socket %d to client %d%s', $i, $i, "\n");
            }
            $read[$i] = $clients[$i]['socket'];
        }
    }
    if($debug) {
        var_dump($read);
    }
    // Any changed sockets?
    // $write and $except are only placeholders
    $changed_sockets = socket_select($read, $write = NULL, $except = NULL, 0);
    if($debug === true){
        printf('Changed sockets: %d%s', $changed_sockets, "\n");
    }
    // Handle new connections
    if(in_array($socket, $read)) {
        for($i = 0; $i < MAX_CLIENTS; $i++) {
            if(!isset($clients[$i])) {
                $clients[$i]['socket'] = socket_accept($socket);
                socket_getpeername($clients[$i]['socket'],$ip);
                $clients[$i]['ip'] = $ip;
                printf('Accepting connection into client %d from %s%s', $i, $ip, "\n");
                break;
            }
            // } elseif($i == MAX_CLIENTS - 1) {
                // echo 'Too many clients connected!', "\n";
            // }
            if($changed_sockets < 1) {
                continue;                
            }
        }
    }
    if($debug) {
        var_dump($clients);
    }

    for($i = 0; $i < count($clients); $i++) {
        $client = $clients[$i];
        // Has our client socket seen any changes?
        if(in_array($client['socket'], $read)) {
            printf('Client %d has changed! Reading...%s', $i, "\n");
            $data = socket_read($client['socket'], 1024);
            if($data === false) {
                $error = socket_strerror(socket_last_error());
                printf('An error occured...%s%s', $error, "\n");

            }
            printf("Read raw data %s from client %i%s", $data, $i, "\n");
            if($data === null) {
                // disconnected
                unset($clients[$i]);
            }

            $data = trim($data);
            if($data == 'exit') {
                printf('Received exit command from client%s', "\n");
                socket_close($clients[$i]['socket']);
            } elseif($data) {
                // Strip whitespace
                printf('Received data: %s from client %d%s', $data, $i, "\n");
                $output = sprintf('%s%s%s', $data, "\n", chr(0));
                socket_write($client['socket'], $output);
            }
        }
    }

    // reset debug
    $debug = false;
}

socket_close($socket);

【问题讨论】:

  • 你的脚本真的在运行吗? localhost 实际上是服务器运行的地方吗?
  • 当然它正在运行 - 它怎么能输出那个错误?它绝对必须在 localhost 上运行,否则 telnet 会抱怨... ;)
  • Touche ;) 这就是我读得太快的结果。
  • 哦,好吧,每个人都会在某个时候发生。 :)

标签: php sockets


【解决方案1】:

你还没有连接到任何东西。 你需要:

socket_connect($socket, $address, $service_port);

在 if 语句中查看是否可以连接。

【讨论】:

  • 嗯..我在 socket_listen() 下添加了 socket_connect()。还是没有运气。
  • 是的。此外,当我第一次运行脚本时,我现在收到此错误:PHP Warning: socket_connect(): unable to connect [106]: Transport endpoint is already connected in /home/neen/php-irc/proxy.php on line 20
  • 您使用的端口是否开放?
  • 嗯。我认同。奇怪的是我 am 能够通过 telnet 发送数据,并且该数据被写回到 telnet..不管错误。所以我很确定端口必须打开。我确实安装了 IPtables,但我认为它不会阻止 localhost 上的任何内容。
  • 另外,我调用socket_read() 的套接字本身已经通过socket_select() 和后来的socket_accept()(第60 和68 行)。
【解决方案2】:

问题是它试图从$clients[0] 读取。哪个不是要读取的有效客户端。我只是将最后两个 for 循环更改为在 1 处开始 $i

到目前为止,在我的测试中,这似乎没有任何不利影响。错误消失了,我所有的客户端实例似乎都工作正常。

【讨论】:

    猜你喜欢
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-13
    • 2018-06-22
    相关资源
    最近更新 更多