3

I'm trying to create a socket connection from a php script to a local server (Qt, QLocalServer) but I'm having trouble just creating a connection on the php side.

<?php
error_reporting(E_ALL);
ini_set('display_errors', 'On');


set_time_limit(0);
ob_implicit_flush();

echo 'usr='. get_current_user().'<br/>';

$address = 'localhost';
$port = 4444; //Different port numbers produce same result

if (($sock = socket_create(AF_UNIX, SOCK_STREAM, 0)) === false) 
{
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
    exit();
}

 if (socket_bind($sock, $address, $port) === false) 
{
    echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
    exit();
}

...

This results in

usr=root Warning: socket_bind(): unable to bind address [98]: Address already in use in /var/www/nbr/socket.php on line 28 socket_bind() failed: reason: Address already in use

I've tried a number of things which give indications of what the problem may be, but not how to resolve it. socket_getsockname produces garbage when I try to echo the address and port information, but if I change AF_UNIX to AF_INET, and add

$addr = ""; $pt = "";    
echo "Socket name ok: " . socket_getsockname($sock, &$addr, &$pt) . '<br/>';
echo $addr .    ", " . $pt . '<br/>';

the result is

Socket name ok: 1

0.0.0.0, 0

So is address/port just never set properly somehow? Also, subsequent socket_get_option($sock, 0, SO_REUSEADDR) fails with AF_UNIX, succeeds with AF_INET but I still get the address unavailable error.

What am I doing wrong?

hakre
  • 193,403
  • 52
  • 435
  • 836
Matt Phillips
  • 9,465
  • 8
  • 44
  • 75
  • 1
    AF_UNIX is a unix local domain socket - basically a file somewhere on your machine. As such there's no "address" or "port", since it's a file. AF_INET means a TCP/IP socket, for which there IS a port/address. – Marc B Apr 11 '11 at 19:03
  • @Marc A local domain socket is what I want--I didn't know it was a file. Will editing it in some way help my issue, and if so you know where it is, or how I can find it? – Matt Phillips Apr 11 '11 at 19:21
  • If you just want to read from a socket that already exists, then just use the regular fopen/fread/fclose stuff, otherwise this other answer should help: http://stackoverflow.com/questions/307692/simplest-way-to-open-and-use-a-socket-in-c – Marc B Apr 11 '11 at 19:26

2 Answers2

3

socket_bind is used to bind a socket on the local machine. Binding a socket means reserve a address/port for a socket. You usually use it for a listener (server) not a client. In your case, since the server (Qt) is already started, then the address is already in use, so socket_bind will fail.

If you want to connect to a socket, use socket_connect:

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!socket_connect($socket, 'localhost', 4444)) {
    die('failed');
}

If you want to connect to a local socket (i.e.: through a socket file, and not through TCP/UDP):

$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
if (!socket_connect($socket, '/var/run/mysqld/mysqld.sock')) {
    die('failed');
}
netcoder
  • 66,435
  • 19
  • 125
  • 142
  • Your method for TCP/IP sockets worked fine--thank you! I'm now in the process of getting this to work for local sockets. – Matt Phillips Apr 11 '11 at 21:16
2

First clear use port:

<?PHP
$port= 4444;
$cmd = explode("*", str_replace(array("/"), "*",
    str_replace(" ","",shell_exec("netstat -tulpn | grep :".$port))));
if (count($cmd)>1) {  //if found use port
    shell_exec("kill -9 " . $cmd[1]);
}
.
.
.
.code
Utopia
  • 663
  • 7
  • 8