2017-04-17 97 views
0

我正尝试使用PHP连接smtp主机(yahoo,mail,gmail等),并检查响应。使用PHP套接字获取来自SMTP服务器的响应

更确切地说 - 是否绑定来自特定主机的IP超时。

请注意,我没有检查是否能够访问SMTP主机的主IP,我需要检查IP是否绑定在接口上。

我能够连接到套接字并绑定IP,但我没有输出。 这是我的代码:

<?php 


function error() { 
    $strerr = socket_last_error(); 
    $strmsg = socket_strerror($strerr); 
    return $strmsg; 
} 

$ip = $argv[1]; 
$port = 25; 
$hosts = array(
    "smtp.gmail.com", 
    "mailin-01.mx.aol.com", 
    "mx2.hotmail.com", 
    "mta7.am0.yahoodns.net" 
); 
$host = "smtp.gmail.com"; 

    foreach ($hosts as $key) { 
    if (!($sock = socket_create(AF_INET, SOCK_STREAM, 0))) { 
     echo error(); 
    } 
    if (!socket_bind($sock, $ip)) { 
     echo "Unable to bind to specific IP."; 
    } 

    //Check can we connect to the socket 
    if (!socket_connect($sock, $key, $port)) { 
     echo error() . "\n"; 
    } 
    else { 

     if (socket_recv($sock, $buf, 150, MSG_PEEK) === FALSE) { 
      echo error() . "\n"; 
     } 
     echo $buf; 

    } 
    socket_shutdown($sock); 
    socket_close($sock); 
} 

我从cli运行脚本。

回答

1
  if (socket_recv($sock, $buf, 500, MSG_WAITALL) === FALSE) { 

你正在等待服务器发送500个字节。如果来自服务器的欢迎消息较短,则您仍等待500字节,因为您已明确设置了MSG_WAITALL。但是服务器不会发送更多数据,也不会关闭连接(这会使recv返回),因为它正在等待客户端继续使用SMTP对话框。这意味着你被困在这条线上。

+0

Steffen Ullrich:谢谢你的帮助!我已将标志更改为'MSG_PEEK',并能够获得某种(类型)的响应。什么麻烦我,我不知道我会收到完整的缓冲区,并且这个值可以变化吗?我不需要与SMTP通信,我只需要查看服务器对特定IP的回复。如果你看一下更新的代码,我会很感激,并让我知道这是正确的方式。非常感谢! – fugitive

+0

@fugitive:我不知道你为什么不简单地调用'socket_recv'没有任何标志。除此之外,要确保您拥有了解SMTP协议所需的一切,并解析相应的数据。在最简单和最常见的情况下,您只能得到一行,但可能会有更多行。有关更多信息,请参阅[SMTP标准](https://tools.ietf.org/html/rfc5321)。 –