Report this

What is the reason for this report?

Fsockopen UDP connection problem

Posted on May 13, 2017

I am currently developing an APP that makes A UDP connection to another host to send commands (old quake3 engine game server) so you can moderate your gameserver without having to boot the game up on your pc.

I’m using laravel (overkill, but I’m learning the framework as well) and locally it works just fine, I can send the command and retrieve the message just as i want it to be. Now when deploying, the app doesn’t seem to work anymore, it doesn’t send any commands and I can’t seem to debug that, udp doesn’t have status (sometimes shows it connected even though the host is dead) so I’m running out of ideas, the firewall is set-up to allow outgoing UDP/TCP connections(I’ve tried with the firewall disabled as well) to the port I’m sending commands to (29070) and when asking the support about any possible blocking they said no. As you guys are probably way more experienced than me, is this a PHP problem or a VPS one?

$this->fp = fsockopen($this->host, $this->port, $this->errno, $this->errstr, 5);
        socket_set_timeout($this->fp, 5);   

and if I do

if ($this->fp)
    echo 'sucess';

It echoes out sucess, but you can’t really trust that when it comes to UDP connections.

How should I proceed?

Thanks.

ps used lemp and lamp on ubuntu 16.04

also I’ve looked around for another laravel host service and none of them accept outgoing and/or incoming UDP connection, which kill’s my application, so if any of you have any ideas please share, i’m desperate.



This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

@Vanker

Are you remembering to add udp:// in front of the server address? http://php.net/manual/en/function.fsockopen.php#example-5028

@Vanker

It’s really dependent on what you’re passing as $host. I’ll use 111.222.33.44 as our fake IP.

Instead of using something such as:

$this->fp = fsockopen('111.222.33.44', 29070, $this->errno, $this->errstr, 5);

… then it most likely will fail or cause problems. Instead, I’d recommend prefixing the IP with udp.

$this->fp = fsockopen('udp://111.222.33.44', 29070, $this->errno, $this->errstr, 5);

I created a very basic function to test fsockopen, this is what I used.

function udpStatus( $host, $port )
{
    $fp = fsockopen( "udp://" . $host, $port, $errNum, $errStr, 1.0 );

    if ( ! $fp )
    {
        return false;
    }
    else
    {
        fclose( $fp );

        return true;
    }
}

In the function, you can see that $host is prefixed with udp://. We can then run a conditional check using:

if ( udpStatus( 'HOST_OR_IP', 29070 ) )
{
    echo 'Connection Status: Success';
}
else
{
    echo 'Connection Status: Failed';
}

Replace HOST_OR_IP with the host or IP you’re connecting to.

With the udp:// prefix, the result from one Droplet connecting to another is Success. If we remove the prefix from the function, it fails.

@Vanker

Doing a little more digging :-). On the same two NYC 3 Droplets, I setup one droplet as a sender and the other as a receiver for UDP.

One the first droplet, I created a file called udp.php and within it, I used the core example that PHP provides for socket_create.

<?php
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

$msg = "Ping!";
$len = strlen($msg);

socket_sendto($sock, $msg, $len, 0, 'REMOTE_IP', 29070);
socket_close($sock);

Where REMOTE_IP is the IP of the second Droplet that is supposed to receive the message. All the above is going to do is send a message “Ping!”.

On the second Droplet, I created a PHP file called receiver.php and within it, I placed:

<?php
//Create socket.
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if (!$socket) { die("socket_create failed.\n"); }

//Set socket options.
socket_set_nonblock($socket);
socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
if (defined('SO_REUSEPORT'))
    socket_set_option($socket, SOL_SOCKET, SO_REUSEPORT, 1);

//Bind to any address & port 29070.
if(!socket_bind($socket, '0.0.0.0', 29070))
    die("socket_bind failed.\n");

//Wait for data.
$read = array($socket); $write = NULL; $except = NULL;
while(socket_select($read, $write, $except, NULL)) {

    //Read received packets with a maximum size of 5120 bytes.
    while(is_string($data = socket_read($socket, 5120))) {
        echo $data;
    }

}

That snippet came from here

On the second droplet, to start the receiver, all I did was run php receiver.php from the command line. Since it’s within a while loop, it’ll keep running until I exit the script.

I then went to the other droplet and ran php udp.php and “Ping!” shows up on the other end, as was expected.

So you may want to look in to the Sockets Library instead of using fsockopen in this particular case.

http://php.net/manual/en/book.sockets.php

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.