2

I use socket_create() to create socket Resource,then I bind an IP address to it by socket_bind(), its works fine;

But after a while(more than 30 minutes) in line socket_read($sock, 2048) this error thrown :

"PHP Warning: socket_read(): unable to read from socket [104]: Connection reset by peer in test.php on line 198".

This is my simplified code:

$this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// check if tcp socket ceated or not
if ($this->sock === false) {
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
     die("Couldn't create socket: [$errorcode] $errormsg");
}

// Bind the source address
socket_bind($this->sock, $this->ip);
// Connect to destination address
socket_connect($this->sock, $this->mxHost, $this->port);
$buf = socket_read($this->sock, 2048);

This piece of code make a SMTP(port 25) connection to a MX Host at the other side. Maybe it's the fault on the other side of your connection, But how can I detect that the other side isn't ready for the connection right now. In the other word how can I find out the "Connection reset by peer" occurred?

Arash Mousavi
  • 2,110
  • 4
  • 25
  • 47

2 Answers2

2

You should check if socket_connect() was successful before reading from it.

so you could rewrite your code like this:

-- UPDATED --

$this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// Bind the source address
socket_bind($this->sock, $this->ip);
// Connect to destination address
if (socket_connect($this->sock, $this->mxHost, $this->port)) {
    // suppress the warning for now since we have error checking below
    $buf = @socket_read($this->sock, 2048);

    // socket_read() returns a zero length string ("") when there is no more data to read.
    // This indicates that the socket is closed on the other side. 
    if ($buf === '') 
    { 
        throw new \Exception('Connection reset by peer'); 
    } 
} else {
    // Connection was not successful. Get the last error and throw an exception
    $errorMessage = socket_strerror(socket_last_error());
    throw new \Exception($errorMessage);
}
dnshio
  • 914
  • 1
  • 8
  • 21
  • 1
    I add some code look like yours, but socket connected successfully, and passed checking if statement, then on socket_read line throws the error. – Arash Mousavi Oct 28 '14 at 16:38
  • I've updated the code so that it checks if the socket_read returned any data. – dnshio Oct 28 '14 at 16:44
  • 2
    I put socket_connect in the `if` statement, but socket_connect returns true, but socket_read throws that error. :( – Arash Mousavi Oct 30 '14 at 19:11
  • Wouldn't your code throw a connection reset error even if the server is fully there? You only check for an empty string, that can be timeout, connection reset or simply a server that didn't send data. – John Jul 06 '18 at 02:28
1

Hmm... Your peer reset the connection. Maybe it's the fault on the other side of your connection ? A timeout mechanism may be running on the other side.

You could test the socket before you write to it with the socket_last_error function and recreate the connection on a disconnection.

itsafire
  • 5,607
  • 3
  • 37
  • 48
  • socket_last_error() doesn't shows any error after socket_create(). – Arash Mousavi Oct 28 '14 at 16:40
  • But does it show errors just before you execute the expression that's causing the warning at a given time ? You should test your socket before issue a `socket_read`. In case of an error reported by 'socket_last_error` recreate your SMTP session. By doing the whole socket_create part again. – itsafire Oct 28 '14 at 18:34