无法通过linux上的套接字连接到本地MySQL服务器

Posted

技术标签:

【中文标题】无法通过linux上的套接字连接到本地MySQL服务器【英文标题】:Can't connect to local MySQL server through socket on linux 【发布时间】:2015-04-11 20:44:41 【问题描述】:

我尝试在 ubunto 上运行一个 php 脚本,每次我使用 sudo php -f /opt/lampp/htdocs/scanner/server/start.php 运行它时都会收到此消息。

服务器:正在运行...

PHP 致命错误:带有消息的未捕获异常“PDOException” 'SQLSTATE[HY000] [2002] 无法通过连接本地 mysql 服务器 套接字'/var/run/mysqld/mysqld.sock'(2)'在 /opt/lampp/htdocs/scanner/server/start.php:26 堆栈跟踪: /opt/lampp/htdocs/scanner/server/start.php(26): PDO->__construct('mysql:host=loca...', 'root', 'datakvarnen') /opt/lampp/htdocs/scanner/server/start.php(51): openConnection() main 在第 26 行的 /opt/lampp/htdocs/scanner/server/start.php 中抛出

我试过php -m 我明白了

[PHP 模块] bcmath bz2 calendar Core ctype date dba dom ereg exif fileinfo filter ftp gettext hash iconv json libxml mbstring mhash mysql mysqli openssl pcntl pcre PDO pdo_mysql Phar posix readline 反射会话 shmop SimpleXML soap sockets SPL 标准 sysvmsg sysvsem sysvshm tokenizer wddx xml xmlreader xmlwriter zip zlib

[Zend 模块]

我用sudo yum install php-pdosudo yum install php-pdo_mysql 得到的所有信息都说它已经安装了。

编辑:这是整个 start.php 文件

<?php

$ip     = "127.0.0.1";
$port   = 5012;

error_reporting(E_ALL);

set_time_limit(0);
ob_implicit_flush();

if(!$server = socket_create(AF_INET, SOCK_STREAM, 0))
    echo socket_strerror(socket_last_error()); exit;


if(!socket_bind($server, $ip, $port))
    echo socket_strerror(socket_last_error()); exit;


if(!socket_listen($server, 5))
    echo socket_strerror(socket_last_error()); exit;


echo "Server: Running...\n\n";

function openConnection($db = "scanner")
    $pdo = new PDO("mysql:host=localhost;dbname=$db;",'root','datakvarnen');
    $pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo -> exec("SET CHARACTER SET utf8");
    return $pdo;


function sendMessage($connection, $message)
    $message .= "\r\n".chr(0);
    socket_write($connection, $message, strlen($message));
    usleep(5);


function readMessage($s)
    //TODO: Fix so it can read any lenght
    $message = @socket_read($s, 1024*10);

    if($message === false)
        return false;
    

    return $message;


//The server is added in the $clients
//The reason for this is because new connection comes as read.
openConnection();
$clients = array();
$null = null;

while(true)
    //Copy $clients so the list doesn't get modified by socket_select();
    $read = $clients;
    $write = $clients;
    $read[] = $server;

    //Wait for read or write
    $ready = socket_select($read, $write, $null, 0);

    //Check if the servers is among the $read clients
    //If it is, then a someone new is trying to connect.
    if(in_array($server, $read))
        //Search to find the server in $clients
        //It's needed since socket_select() demand we use $read instead of $server
        foreach($read as $client)
            if($client == $server)
                //We found the new connection, and accepts it.
                //TODO: Make a verify code to check it's a scanner.jar that joins
                $new = socket_accept($client);
                $clients[] = $new;
                continue 2;//<-- $server was found, so no need to search anymore.
            
        
    

    foreach($read as $client)
        $message = readMessage($client);

        if($message === false)
            //Socket is closed or lost connection
            $key = array_search($client, $clients);
            unset($clients[$key]);
            continue 2;
        else
            //You got the message
            echo $message;
        
    

    foreach($write as $client)
        sendMessage($client,rand(0,99999));
    

    sleep(1);


socket_close($server);

【问题讨论】:

您是否安装并运行了mysql?你确定那是你的套接字的位置吗? 我确定mysql正在运行,因为我的主页可以连接到它,你的socket位置是什么意思? 套接字是一个文件。 PHP/PDO 正在寻找/var/run/mysqld/mysqld.sock 的套接字文件,这是正确的位置吗?如果您的主页正在运行,它是否使用 PDO? 不,这不是正确的位置,我没有运行 mysqld 文件夹,是的。我的主页使用了 PDO,并且在同一台计算机上。 【参考方案1】:

不,这不是正确的位置,我没有运行 mysqld 文件夹

好的,那么您需要更改套接字的位置。您可以通过在 DSN 中指定每个 PDO 实例级别来执行此操作,也可以通过在 php.ini 中指定来批量执行此操作。

对于PDO_Mysql DSN 的文档中定义的 PDO:

$pdo = new PDO("mysql:unix_socket=/path/to/your/mysqld.sock;dbname=$db;",'root','datakvarnen');

php.ini 中找到mysql.default_socket 并更改它:

mysql.default_socket = /path/to/your/mysqld.sock

虽然它对我来说是个谜,除非它使用 TCP DSN(使用 IP 地址或主机名而不是 localhost 作为 DSN 中的主机属性)或者您使用不同的 php.ini用于 CLI 和网络服务器(这并不少见)。

【讨论】:

以上是关于无法通过linux上的套接字连接到本地MySQL服务器的主要内容,如果未能解决你的问题,请参考以下文章

Mysql 无法通过 Amazon EC2 上的套接字连接到本地服务器

无法通过套接字连接到本地 MySQL 服务器

无法通过套接字 '/tmp/mysql.sock' 连接到本地 MySQL 服务器 (2)

无法通过套接字 '/var/mysql/mysql.sock' 连接到本地 MySQL 服务器 (38)

无法通过套接字 '/var/mysql/mysql.sock' 连接到本地 MySQL 服务器 (38)

Rails 应用程序无法连接到 mysql,无法通过套接字 '/var/run/mysqld/mysql.sock' 连接到本地 MySQL 服务器 (2) (Mysql2::Error)