简体   繁体   English

通过代理的PHP套接字连接

[英]PHP Socket connection through proxy

I'm building a webmail-client-like application, and I'm having issues connecting to POP3 through our beloved corp proxy. 我正在构建一个类似于webmail-client的应用程序,但在通过我们心爱的corp代理连接到POP3时遇到了问题。

Due to client requirements, I'm obligated to use sockets to talk with their POP3 server (they actively specified this is mandatory and they also explained they have a proxy between the app server and the POP) so besides enabling me to work this is kind of the only option I have. 由于客户的要求,我有义务使用套接字与他们的POP3服务器进行通信(他们积极地指定这是强制性的,并且他们还解释说他们在应用程序服务器和POP之间具有代理),因此除了使我能够工作外,还很善良我唯一的选择。

Does anyone know how to do this? 有谁知道如何做到这一点?

UPDATED TO ADD: 更新为:

Here's my socket handler: 这是我的套接字处理程序:

<?php
class Socket {
  protected $handle = null;
  protected static $status = null;
  public function __construct($server, $port){
    if(!$this->connect($server, $port)){
      throw new UnexpectedValueException("Server $server in port $port unreachable.");
    }
  }
  public static function getStatus(){
    return self::$status;
  }  
  public function write($string){
    fputs($this->handle, $string);
    return $this;
  }
  public function read($lines = 1){
    $lines = abs((int)$lines);//people can be morons
    for($i = 0; $i < $lines; $i++){
      $response []= $this->getLine();
    }
    if($lines==1){
      $response = $response[0];
    }
    return $response;
  }
  public function connect($server, $port){
    $errNo = 0;
    $handle = fsockopen($server, $port);
    if(!$handle){
      return false;
    }
    $this->handle = $handle;
    return $this;
  }
  public function disconnect(){
    if(gettype($this->handle)=='resource'){
      fclose($this->handle);
    }
  }
  public function __destruct(){
    $this->disconnect();
  }
  protected function getLine(){
    return fgets($this->handle);
  }
}

I'm using it like so: 我这样使用它:

$plug = new Socket('mx.mailserver.com',110);
$plug->write("USER $username\n")->read();
$could = $plug->write("PASS $password\n")->read();
if(strpos($could,'+OK')!==false){
  $mails = $plug->write("STAT\n");
}

And right now our proxy is not letting me out; 而现在,我们的代理人并没有放过我。 situation I would like to know how to revert. 情况我想知道如何还原。

First, have you tested with telnet - ie if you are on the same server / workstation that the PHP script is running on, and you issue: 首先,您是否已使用telnet进行了测试-即,如果您与运行PHP脚本的服务器/工作站位于同一服务器/工作站上,则发出:

telnet mx.mailserver.com 110

Do you get the greeting? 你收到问候了吗? (you're also not reading that - so your read from the command where you send the username is going to get that as a response, so your code will work but largely by accident. (您也没有读过-因此,您从发送用户名的命令中读取的内容会作为响应得到,因此您的代码可以正常工作,但很大程度上是偶然的。

If you can't get it to work via telnet then stop and get that working first - no point proceeding otherwise. 如果您无法通过telnet使其正常工作,请先停止并使其正常工作-否则就没有任何意义了。

You may need to send \\r\\n at the end of each command. 您可能需要在每个命令的末尾发送\\ r \\ n。

$plug->write("USER $username\r\n")->read();

So you need to do something like: 因此,您需要执行以下操作:

$plug = new Socket('mx.mailserver.com',110);
$greeting = $plug->read(); // check this said +OK
$plug->write("USER $username\r\n")->read(); // check this said +OK
$could = $plug->write("PASS $password\r\n")->read();
if(strpos($could,'+OK')!==false) {
    $mails = $plug->write("STAT\r\n");
}

I'm not entirely sure about your strpos() line - but I can't test that right now. 我不确定您的strpos()行是什么,但是我现在无法测试。

As I say, before you do ANYTHING else verify that it all works ok on Telnet. 就像我说的那样,在进行任何其他操作之前,请先验证它在Telnet上都可以正常工作。

If it does, then monitor the server logs (if possible) and see whether you're getting in touch with the POP3 server and what it's getting. 如果是这样,则监视服务器日志(如果可能),并查看您是否与POP3服务器保持联系以及它将获得什么。

Here's an example sequence: 这是一个示例序列:

telnet pop.blah.com 110 telnet pop.blah.com 110

+OK Welcome to MailEnable POP3 Server

USER matthew 用户马修

+OK

PASS mypassword 通过密码

+OK 

STAT 统计

+OK 0 0

Hope this helps. 希望这可以帮助。

Use this for client https://github.com/clue/php-socks 将此用于客户端https://github.com/clue/php-socks

Use this for proxy server https://github.com/clue/psocksd 将此用于代理服务器https://github.com/clue/psocksd

If your server has more than one public IP and you need these IP act as proxy outgoing, use this for proxy server https://www.inet.no/dante/ 如果您的服务器具有多个公共IP,并且您需要将这些IP用作代理传出,请将其用于代理服务器https://www.inet.no/dante/

Guide to configure proxy to have multi outgoing ip: http://www.inet.no/dante/doc/faq.html#multiple_external_ips 将代理配置为具有多个传出IP的指南: http : //www.inet.no/dante/doc/faq.html#multiple_external_ips

Example config to have multi outgoing ip: http://wiki.jokeru.ro/dante-socks-server 具有多个传出IP的示例配置: http : //wiki.jokeru.ro/dante-socks-server

They all work for me 他们都为我工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM