【问题标题】:Connect as client in a remote socket server在远程套接字服务器中作为客户端连接
【发布时间】:2019-12-27 00:22:20
【问题描述】:

我需要构建一个简单的 PHP 服务套接字,以作为客户端与远程套接字服务器连接,然后进行 lintening。问题是我需要连接主机 URL 而不是主机 IP。

我试过socket_create() 方法,但它只使用IP 连接。我尝试过的其他方法是stream_socket_server(),它允许 URL 连接,但我无法继续收听以接收响应。

echo "Socket started...\n";

$server = 'ssl://sockserver.com/moreurl/params?56298';
$host = "sockserver.com";
$port = 80;
set_time_limit(0);

$socket = socket_create(AF_INET, SOCK_STREAM, 0);
$result = socket_connect($socket, $server, $port);
socket_bind($socket, $host);
socket_listen($socket);

while (true) {
  $result = socket_read ($socket, 1024);
  if($result){
    echo "Reply From Server  :".$result;
  }
}

socket_close($socket);

所以,我需要使用类似主机的 URL 来监听远程服务器 Socket 作为 PHP 客户端。

【问题讨论】:

  • 您的代码中缺少socket_bindsocket_listen...如果不将套接字绑定到实际IP 地址,您将无法建立连接...
  • @LarsStegelitz,谢谢你的回复,我用这个方法改变了我的代码,我对错误感到惊讶:“socket_read():无法从套接字[107]读取:传输端点是未连接”。这个结构正确吗?

标签: php sockets websocket fsockopen


【解决方案1】:

实际上,您需要让自己熟悉套接字编程...例如,您的 $address 是一个 URL - 但套接字不理解 URL。您必须使用 IP 地址(对于 AF_INET)或 Unix 套接字路径(对于 AF_UNIX)。

我将为您提供 2 个脚本,一个非常基本的套接字服务器 + 套接字客户端……您可以随意使用它。

服务器:

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_bind($socket, '0.0.0.0', 9999);
if (socket_listen($socket)) {
    $nsocket = socket_accept($socket);

    $exit = false;
    while(!$exit && $s = socket_read($nsocket, 100)) {
        $s = trim($s);

        if ($s == 'quit') {
            $exit = true;
            $a = 'Bye';
        }
        else {
            echo 'Received "'.$s.'" from '.$nsocket . PHP_EOL;
            $a = 'You wrote "'.$s.'"';
        }

        socket_write($nsocket, $a."\n");
    }
    socket_write($nsocket, "Bye\n");
    socket_close($nsocket); 
}

客户:

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_connect($socket, '127.0.0.1', 9999);
echo '> ';
while( ($data = fgets(STDIN)) && trim($data) != 'quit') {

    if (strlen($data))
        socket_write($socket, $data);
    $answer = '';
    while($ret = socket_read($socket, 1)) { 
        $answer .= $ret;
        if ($ret == "\n") break;
    }
    echo '< '.$answer;
    echo '> ';
}

【讨论】:

  • 再次感谢。我的英语不太好,所以也许我不能很好地解释我的问题。我的问题正是这样:我需要使用 URL Socket 服务器而不是 IP 创建一个客户端,因为我必须传递一些参数。你觉得有可能吗?
  • 没有“URL 套接字服务器”之类的东西。套接字位于 OSI 第 4 层(传输),而加密 (ssl)、dns 或 http 位于第 6 层(表示)。协议栈只能从较高层到较低层工作。第 4 层不理解 URL,因为该概念是在更高级别上引入的。 TCP 或 UDP 使用 IP 地址(因为 IP 在网络第 3 层上定义)
  • 对,这对我来说完全有意义...所以我将尝试仅使用 IP 连接并在握手时通过标头发送参数。非常感谢您的帮助!!
【解决方案2】:

O 使用ratchetphp/Pawl library at Github 解决了我的问题。该库允许在 WSS 中作为客户端进行连接。

【讨论】: