This will give you a simple port-checker.
Note that on production-machines, you might want to alter the error reporting-level,
since unsuccessful connects will give you a "No connection could be made because
the target machine actively refused it"-error in the log.
Under Windows, make sure you enable the php_sockets.dll extension in your php.ini.
<?php
$address=$_SERVER['REMOTE_ADDR'];
if (isset($_REQUEST['port']) and
(!strlen($_REQUEST['port'])==0))
$port=$_REQUEST['port'];
else
unset($port);
if (isset($port) and
($socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) and
(socket_connect($socket, $address, $port)))
{
$text="Connection successful on IP $address, port $port";
socket_close($socket);
}
else
$text="Unable to connect<pre>".socket_strerror(socket_last_error())."</pre>";
echo "<html><head></head><body>".
$text.
"</body></html>";
?>
Greetz,
Peter.
socket_connect
(PHP 4 >= 4.1.0, PHP 5)
socket_connect — ソケット上の接続を初期化する
説明
ソケットリソース socket を用いて、 address への接続を初期化します。 このリソースは、socket_create() で作成した有効なソケットリソースである必要があります。
パラメータ
- socket
-
- address
-
パラメータ address には、 socket の種類が AF_INET の場合はドット区切り表記の IPv4 アドレス (例: 127.0.0.1)、 IPv6 サポートが有効で socket の種類が AF_INET6 の場合は IPv6 アドレス (例: ::1)、 AF_UNIX の場合は Unix ドメインソケットのパス名を指定します。
- port
-
パラメータ port は AF_INET ソケット あるいは AF_INET6 に接続する場合にのみ必須となり、 接続するリモートホストのポートを指定します。
返り値
成功した場合に TRUE を、失敗した場合に FALSE を返します。 エラーコードは、 socket_last_error() により取得できます。 このコードを socket_strerror() に渡すことにより、 エラー内容を表すテキストを得ることができます。
注意: ソケットが非ブロッキングモードの場合、この関数は FALSE を返し、エラー Operation now in progress を発生させます。
参考
- socket_bind() - ソケットに名前をバインドする
- socket_listen() - ソケット上で接続待ち(listen)する
- socket_create() - ソケット(通信時の終端)を作成する
- socket_last_error() - ソケットの直近のエラーを返す
- socket_strerror() - ソケットエラーの内容を文字列として返す
socket_connect
29-Oct-2009 07:29
02-Sep-2009 04:40
This will print the banner from a true 'telnet' server (router, switch, host, etc).
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 23);
while (TRUE) {
$r = array($socket);
$c = socket_select($r, $w = NULL, $e = NULL, 5);
foreach ($r as $read_socket) {
if ($r = negotiate($read_socket)) {
var_dump($r);
exit;
}
}
}
function negotiate ($socket) {
socket_recv($socket, $buffer, 1024, 0);
for ($chr = 0; $chr < strlen($buffer); $chr++) {
if ($buffer[$chr] == chr(255)) {
$send = (isset($send) ? $send . $buffer[$chr] : $buffer[$chr]);
$chr++;
if (in_array($buffer[$chr], array(chr(251), chr(252)))) $send .= chr(254);
if (in_array($buffer[$chr], array(chr(253), chr(254)))) $send .= chr(252);
$chr++;
$send .= $buffer[$chr];
} else {
break;
}
}
if (isset($send)) socket_send($socket, $send, strlen($send), 0);
if ($chr - 1 < strlen($buffer)) return substr($buffer, $chr);
}
14-Apr-2009 07:52
rbarnes' tip is helpful, but I found that I needed to add a check for SOCKET_EISCONN in the while loop:
...
$error = socket_last_error();
if ($error == SOCKET_EISCONN) {
$connected = true;
break;
}
...
At least on Mac OS X 10.5.
18-Sep-2008 07:15
Hi there!
For the TCP connections: socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
In case you're having problems in socket_connect() with socket_strerror() = "Permission denied", you may be having a SELinux config issue.
Check if SELinux is enabled:
# /usr/sbin/sestatus -v
In case it is, you can just type the command:
# setsebool httpd_can_network_connect=1
That's it... I read you had to reboot, but I didn't and it worked fine anyway. More info, you may check:
http://arkiv.netbsd.se/?ml=squirrelmail-users&a=2005-11&t=1523021
15-Jul-2008 05:04
Here is an example of a non-blocking connect which should perform quite a bit faster than the one posted by Seymour below:
<?php
function msConnectSocket($remote, $port, $timeout = 30) {
# this works whether $remote is a hostname or IP
$ip = "";
if( !preg_match('/^\d+\.\d+\.\d+\.\d+$/', $remote) ) {
$ip = gethostbyname($remote);
if ($ip == $remote) {
$this->errstr = "Error Connecting Socket: Unknown host";
return NULL;
}
} else $ip = $remote;
if (!($this->_SOCK = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
$this->errstr = "Error Creating Socket: ".socket_strerror(socket_last_error());
return NULL;
}
socket_set_nonblock($this->_SOCK);
$error = NULL;
$attempts = 0;
$timeout *= 1000; // adjust because we sleeping in 1 millisecond increments
$connected;
while (!($connected = @socket_connect($this->_SOCK, $remote, $port+0)) && $attempts++ < $timeout) {
$error = socket_last_error();
if ($error != SOCKET_EINPROGRESS && $error != SOCKET_EALREADY) {
$this->errstr = "Error Connecting Socket: ".socket_strerror($error);
socket_close($this->_SOCK);
return NULL;
}
usleep(1000);
}
if (!$connected) {
$this->errstr = "Error Connecting Socket: Connect Timed Out After $timeout seconds. ".socket_strerror(socket_last_error());
socket_close($this->_SOCK);
return NULL;
}
socket_set_block($this->_SOCK);
return 1;
}
?>
22-Feb-2008 10:14
This probably sounds like common sense, but it is something nobody i asked thought of... you can't bind the socket to localhost, you must bind it to either the IP your router assigns you, or your public IP address. If you bind to localhost, it will give an invalid resource error.
17-Sep-2005 04:13
If you do want to have a socket_connect operation timeout you can use the following code.
<?php
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($sock);
socket_connect($sock,"127.0.0.1", 80);
socket_set_block($sock);
switch(socket_select($r = array($sock), $w = array($sock), $f = array($sock), 5))
{
case 2:
echo "[-] Connection Refused\n";
break;
case 1:
echo "[+] Connected\n";
break;
case 0:
echo "[-] Timeout\n";
break;
}
?>
This basically makes socket_connect return immediately then you can use socket_select to see how the socket reacted.
well this solution (above) is not right because you cant ping port...
23-Nov-2003 08:05
In reply to the function socket_raw_connect posted by "net_del at freemail dot ru". In the function you give a return value and afterwords you try to close the connection. That won't ever work. I think you want to alter your code ;-)
01-Oct-2003 07:43
here's how you can implement timeouts with the socket functions.
this example works for blocking sockets but will work for both blocking and nonblocking with minor modifications. first call to connect in nonblocking mode returns 115 EINPROGRESS, additional calls return 114 EALREADY if the connection has not already failed or succeeded. once the connection succeeds, the socket resource will be returned.
<?
$host = "127.0.0.1";
$port = "80";
$timeout = 15; //timeout in seconds
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)
or die("Unable to create socket\n");
socket_set_nonblock($socket)
or die("Unable to set nonblock on socket\n");
$time = time();
while (!@socket_connect($socket, $host, $port))
{
$err = socket_last_error($socket);
if ($err == 115 || $err == 114)
{
if ((time() - $time) >= $timeout)
{
socket_close($socket);
die("Connection timed out.\n");
}
sleep(1);
continue;
}
die(socket_strerror($err) . "\n");
}
socket_set_block($this->socket)
or die("Unable to set block on socket\n");
?>
26-Aug-2003 08:54
function socket_raw_connect ($server, $port, $timeout,$request)
{
if (!is_numeric($port) or !is_numeric($timeout)) {return false;}
$socket = fsockopen($server, $port, $errno, $errstr, $timeout);
fputs($socket, $request);
$ret = '';
while (!feof($socket))
{
$ret .= fgets($socket, 4096);
}
return $ret;
fclose($socket);
}
this code for easy raw connect.
Comment by net_del[nkg] (www.nkg.ru)
I am from russia. PHP is good language!
28-Jun-2003 09:20
man page for connect :
EINPROGRESS
The socket is non-blocking and the connection cannot be completed immediately. It is possible to select(2) or poll(2) for completion by selecting the socket for writing. After select indicates writability, use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the reason for the failure).
use socket_getoption($socket,SOL_SOCKET,SO_ERROR) . If you get value 115, it is connecting. If you get value different than 115 and 0, that means that an error has occured (see what error with socket_strerror()).
However, I don't know how does that works under Windows, maybe it wont work at all. It is supposed to work under Linux (man pages said that).
30-Apr-2003 09:12
If you're using non-blocking, be sure not to turn it on until after you connect, otherwise you will get the mesasge:
PHP Warning: socket_connect() unable to connect [115]: Operation now in progress in file.php on line 123
and socket_connect() will return false (even though it will connect).
24-Jul-2002 06:24
I had the same problem with the timeout, and i applied this solution.
It works only on linux PHP, i make a ping to the ip before connect the socket.....
$address = gethostbyname ($ip);
$command = "ping -c 1 " . $address;
$r = exec($command);
if ($r[0]=="r")
{
$socket = socket_create (AF_INET, SOCK_STREAM, 0);
if ($socket < 0) {
echo "socket_create() failed: reason: " . socket_strerror ($socket) . "\n";
} else {
echo "OK.\n";
}
