Bug #66266 [Com]: socket_sendto always returns true
| From: | phpmpan at mpan dot pl | Date: | Thu, 12 Dec 2013 02:34:48 +0000 |
| Subject: | Bug #66266 [Com]: socket_sendto always returns true | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-183246@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=66266&edit=1
ID: 66266
Comment by: phpmpan at mpan dot pl
Reported by: chuck at jumis dot com
Summary: socket_sendto always returns true
Status: Open
Type: Bug
Package: Sockets related
Operating System: Darwin Kernel Version 13.0.0
PHP Version: 5.4.22
Block user comment: N
Private report: N
New Comment:
This is a correct and expected behaviour. Please read some introduction to UDP. Wikipedia provides
basic information on that matter: <https://en.wikipedia.org/wiki/User_Datagram_Protocol>.
UDP is connectionless (hence there is no such thing as "UDP connection"), fire-and-forget
protocol. There is no way to tell if the data was delivered, if it was delivered uncorrupted and
sendto can not detect such condition. If you require such functionality, use TCP or proper
application-level protocol. However, if you require to know synchronously that a particular packet
was not delivered, only application-level protocol will do, and it will be extremely slow (even way
below 1kB/s).
It is possible to implement closed-port detection. If the remote machine cooperates and no devices
on the route block it, one may receive ICMP type 3 code 3 packet. This is how network scanners and
few other applications work. However, such solution is unsuitable for sendto as it requires wating
for the mentioned packet. Also it may only detect errors: no-error conditions may be false
positives.
Also the documentation for
socket_sendto contains no information you have written
about.
Previous Comments:
------------------------------------------------------------------------
[2013-12-12 00:51:13] chuck at jumis dot com
Description:
------------
This always returns true, and the full amount of bytes, even when the remote port is closed. Running
socket_recvfrom simply results in an Unavailable error.
This is in contrast to running something like socat which will return an error after sending data.
Note that the manual does say that UDP connections should return an error following socket_sendto.
I've not been able to find a work-around. At present I simply can not test if the target UDP
port is open. May be an ICMP issue.
Test script:
---------------
$fp = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
$bytes = socket_sendto($fp, $json."\n", strlen($json)+1, 0, $ip, $port);
$fp && $bytes > 0 && socket_last_error($fp) == 0;
Expected result:
----------------
When the remote UDP port is closed, socket_sendto should return false or otherwise socket_recvfrom
should return false.
Actual result:
--------------
The socket pointer and socket_sendto return true -- it is not distinguishable whether or not the
remote UDP port is open.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=66266&edit=1