0

I have created two program one is server and the other one is client for creating chatroom but the issue is when i upload it to server then i get error message

Warning: socket_bind(): unable to bind address [98]: Address already in use 

I have searched all over the web and seen also previous answers related to websockets but the issue is same. It is hosted on Linux CentOs. Below is the code. It is working on localhost i have changed the port number also. Same is the case when i run https://code.google.com/p/phpwebsocket/code. You can get the below code at the following url :http://www.sanwebe.com/2013/05/chat-using-websocket-php-socket. Please help... Thanks

Server.php

<?php
// set some variables
// don't timeout!
set_time_limit(0);
ob_implicit_flush();

$host = "XX.XX.XXX.XX";
$port = "25764";

// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\n");
// bind socket to port
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
// start listening for connections
$result = socket_listen($socket, 3) or die("Could not set up socket listener\n");
//create & add listning socket to the list
$clients = array($socket);
//start endless loop, so that our script doesn't stop
while (true) {
    //manage multipal connections
    $changed = $clients;
    //returns the socket resources in $changed array
    socket_select($changed, $null, $null, 0, 10);
    //check for new socket
    if (in_array($socket, $changed)) {
        $socket_new = socket_accept($socket); //accpet new socket
        $clients[] = $socket_new; //add socket to client array

        $header = socket_read($socket_new, 1024); //read data sent by the socket
        perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake

        socket_getpeername($socket_new, $ip); //get ip address of connected socket
        $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected'))); //prepare json data
        send_message($response); //notify all users about new connection

        //make room for new socket
        $found_socket = array_search($socket, $changed);
        unset($changed[$found_socket]);
    }

    //loop through all connected sockets
    foreach ($changed as $changed_socket) { 

        //check for any incomming data
        while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
        {
            $received_text = unmask($buf); //unmask data
            $tst_msg = json_decode($received_text); //json decode 
            $user_name = $tst_msg->name; //sender name
            $user_message = $tst_msg->message; //message text
            $user_color = $tst_msg->color; //color

            //prepare data to be sent to client
            $response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color)));
            send_message($response_text); //send data
            break 2; //exist this loop
        }

        $buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);
        if ($buf === false) { // check disconnected client
            // remove client for $clients array
            $found_socket = array_search($changed_socket, $clients);
            socket_getpeername($changed_socket, $ip);
            unset($clients[$found_socket]);

            //notify all users about disconnected connection
            $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected')));
            send_message($response);
        }
    }
}
// close the listening socket
socket_close($sock);

function send_message($msg)
{
    global $clients;
    foreach($clients as $changed_socket)
    {
        @socket_write($changed_socket,$msg,strlen($msg));
    }
    return true;
}


//Unmask incoming framed message
function unmask($text) {
    $length = ord($text[1]) & 127;
    if($length == 126) {
        $masks = substr($text, 4, 4);
        $data = substr($text, 8);
    }
    elseif($length == 127) {
        $masks = substr($text, 10, 4);
        $data = substr($text, 14);
    }
    else {
        $masks = substr($text, 2, 4);
        $data = substr($text, 6);
    }
    $text = "";
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i%4];
    }
    return $text;
}

//Encode message for transfer to client.
function mask($text)
{
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);

    if($length <= 125)
        $header = pack('CC', $b1, $length);
    elseif($length > 125 && $length < 65536)
        $header = pack('CCn', $b1, 126, $length);
    elseif($length >= 65536)
        $header = pack('CCNN', $b1, 127, $length);
    return $header.$text;
}

//handshake new client.
function perform_handshaking($receved_header,$client_conn, $host, $port)
{
    $headers = array();
    $lines = preg_split("/\r\n/", $receved_header);
    foreach($lines as $line)
    {
        $line = chop($line);
        if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))
        {
            $headers[$matches[1]] = $matches[2];
        }
    }

    $secKey = $headers['Sec-WebSocket-Key'];
    $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
    //hand shaking header
    $upgrade  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
    "Upgrade: websocket\r\n" .
    "Connection: Upgrade\r\n" .
    "WebSocket-Origin: $host\r\n" .
    "WebSocket-Location: wss://$host:$port/test3/server.php\r\n".
    "Sec-WebSocket-Accept:$secAccept\r\n\r\n";
    socket_write($client_conn,$upgrade,strlen($upgrade));
}
?>

Client.php

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<style type="text/css">
<!--
.chat_wrapper {
    width: 500px;
    margin-right: auto;
    margin-left: auto;
    background: #CCCCCC;
    border: 1px solid #999999;
    padding: 10px;
    font: 12px 'lucida grande',tahoma,verdana,arial,sans-serif;
}
.chat_wrapper .message_box {
    background: #FFFFFF;
    height: 150px;
    overflow: auto;
    padding: 10px;
    border: 1px solid #999999;
}
.chat_wrapper .panel input{
    padding: 2px 2px 2px 5px;
}
.system_msg{color: #BDBDBD;font-style: italic;}
.user_name{font-weight:bold;}
.user_message{color: #88B6E0;}
-->
</style>
</head>
<body>  
<?php 
$colours = array('007AFF','FF7000','FF7000','15E25F','CFC700','CFC700','CF1100','CF00BE','F00');
$user_colour = array_rand($colours);
?>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<script language="javascript" type="text/javascript">  
$(document).ready(function(){
    //create a new WebSocket object.
    var wsUri = "ws://XX.XX.XXX.XX:25764/test3/server.php";     
    websocket = new WebSocket(wsUri); 
    websocket.onopen = function(ev) { // connection is open 
        $('#message_box').append("<div class=\"system_msg\">Connected!</div>"); //notify user
    }

    $('#send-btn').click(function(){ //use clicks message send button   
        var mymessage = $('#message').val(); //get message text
        var myname = $('#name').val(); //get user name

        if(myname == ""){ //empty name?
            alert("Enter your Name please!");
            return;
        }
        if(mymessage == ""){ //emtpy message?
            alert("Enter Some message Please!");
            return;
        }

        //prepare json data
        var msg = {
        message: mymessage,
        name: myname,
        color : '<?php echo $colours[$user_colour]; ?>'
        };
        //convert and send data to server
        websocket.send(JSON.stringify(msg));
    });

    //#### Message received from server?
    websocket.onmessage = function(ev) {
        var msg = JSON.parse(ev.data); //PHP sends Json data
        var type = msg.type; //message type
        var umsg = msg.message; //message text
        var uname = msg.name; //user name
        var ucolor = msg.color; //color

        if(type == 'usermsg') 
        {
            $('#message_box').append("<div><span class=\"user_name\" style=\"color:#"+ucolor+"\">"+uname+"</span> : <span class=\"user_message\">"+umsg+"</span></div>");
        }
        if(type == 'system')
        {
            $('#message_box').append("<div class=\"system_msg\">"+umsg+"</div>");
        }

        $('#message').val(''); //reset text
    };

    websocket.onerror   = function(ev){$('#message_box').append("<div class=\"system_error\">Error Occurred - "+ev.data+"</div>");}; 
    websocket.onclose   = function(ev){$('#message_box').append("<div class=\"system_msg\">Connection Closed</div>");}; 
});
</script>
<div class="chat_wrapper">
<div class="message_box" id="message_box"></div>
<div class="panel">
<input type="text" name="name" id="name" placeholder="Your Name" maxlength="10" style="width:20%"  />
<input type="text" name="message" id="message" placeholder="Message" maxlength="80" style="width:60%" />
<button id="send-btn">Send</button>
</div>
</div>

</body>
</html>

Working Client Code:

<?php
// where is the socket server?
$host    = "XX.XX.XXX.XX";
$port    = "25763";
$message = "Hello Server This is the first message to the server";
echo "Message To server :".$message;
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\n");
// connect to server
$result = socket_connect($socket, $host, $port) or die("Could not connect to server\n");  
// send string to server
socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");
// get server response
$result = socket_read ($socket, 1024) or die("Could not read server response\n");
echo "Reply From Server  :".$result;
// close socket
socket_close($socket);
    // print result to browser
?>

Working Server Code:

<?php
    $host = "XX.XX.XXX.XX";
    $port = "25763";
    // don't timeout!
    set_time_limit(0);
    // create socket
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\n");
    // bind socket to port
    socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
    $result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
    // start listening for connections
    $result = socket_listen($socket, 3) or die("Could not set up socket listener\n");
    // accept incoming connections
    // spawn another socket to handle communication
    $spawn = socket_accept($socket) or die("Could not accept incoming connection\n");
    // read client input
    $input = socket_read($spawn, 1024) or die("Could not read input\n");
    // clean up input string
    $input = trim($input);
    echo "Client Message : ".$input;
    // reverse client input and send back
    $output = strrev($input) . "\n";
    echo $spawn;
    socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n");
    // close sockets
    socket_close($spawn);
    socket_close($socket);
    ?>
user3812616
  • 11
  • 1
  • 7

1 Answers1

0

There's a couple reasons I know of that you will not be able to bind to a certain port. The first is that something has already bound to that port. To see whether this is the case or not, try using netstat:

$ netstat -anl

The other reason you might not be able to bind to a port is that you must be root to bind to what's referred to as "privileged ports". For more on that, read this:

Is there a way for non-root processes to bind to "privileged" ports on Linux?

Community
  • 1
  • 1
oliakaoil
  • 1,615
  • 2
  • 15
  • 36
  • how can i check whether the ports is empty because i have checked many of the ports but the same issue, whether it can be set from the cpanel – user3812616 Jul 07 '14 at 13:51
  • Use the netstat command as I suggested. At the top of the output of that command, all bound addresses and ports will be listed. – oliakaoil Jul 07 '14 at 13:53
  • I have to run netstat command on the server using cpanel because i am new to socket programming i have never done it before – user3812616 Jul 07 '14 at 13:54
  • I'm sorry I don't understand your last comment. You need to run netstat from a shell on the server, which is usually accomplished via ssh. – oliakaoil Jul 07 '14 at 13:56
  • Is there any example hoe to use these commands because i am using cpanel and i have to run on that server. Locally both of the program is running properly. – user3812616 Jul 07 '14 at 14:00
  • You may be able to execute shell commands with PHP using various functions like shell_exec: http://www.php.net/manual/en/function.shell-exec.php. Also read this: http://stackoverflow.com/questions/4701993/using-bash-shell-from-within-php or try something like this: http://sourceforge.net/projects/phpterm/, however keep in mind that if you cannot run your "server PHP script" from a non-webpage context it's not going to work in any case. – oliakaoil Jul 07 '14 at 14:03
  • Sorry if i am wrong i can check the port numbers locally on windows system by c:\>netstat -an but when i upload it to main server through cpanel i.e. OS Linux Centos how then i will be able to check it.. – user3812616 Jul 07 '14 at 14:08
  • You're likely NOT going to be able to run your server script in a shared hosting environment. This technique works locally because you have full access to the server, which in that case is your development machine. To get this same environment somewhere else you need your own server, virtual or otherwise. Please chat me to continue this discussion. – oliakaoil Jul 07 '14 at 14:17
  • So i can't run the script on the shared host. I have to purchase dedicated host. But i have a client server program which is not based on websocket is properly running, i will add it with my above code with the name of running program. – user3812616 Jul 07 '14 at 14:26