有没有办法使用flash.net.Socket检测TCP连接被拒绝?

时间:2010-08-03 14:01:20

标签: flash sockets tcp

有一个flash电影正在使用flash.net.Socket连接到服务器。但是可能存在服务器未运行的情况,因此没有任何东西正在侦听端口套接字连接。

当我执行“telnet hostname port”时,我收到快速连接拒绝错误。但是flash.net.Socket不会调用任何事件(见下文),而是静默等待套接字超时。对我来说,尽可能减少检测不存在的服务器所需的时间非常重要,以便能够重新连接到群集中的另一台服务器。

我尝试了以下活动,但无济于事:

  • 靠近
  • 连接
  • ioError在
  • 的securityError
  • socketData

在这种情况下,这些都不会被调用。

有没有办法使用flash.net.Socket来检测TCP连接被拒绝?

3 个答案:

答案 0 :(得分:0)

如何通过添加<img src='http://target:port/' onerror='noconnect' />捕获连接错误?

答案 1 :(得分:0)

这个怎么样:

package {
    import flash.display.Sprite;

    public class SocketExample extends Sprite {

        public function SocketExample() {
            var socket:CustomSocket = new CustomSocket("localhost", 80);
        }
    }
}

import flash.errors.*;
import flash.events.*;
import flash.net.Socket;

class CustomSocket extends Socket {
    private var response:String;

    public function CustomSocket(host:String = null, port:uint = 0) {
        super(host, port);
        this.timeout=100;
        configureListeners();
    }

    private function configureListeners():void {
        addEventListener(Event.CLOSE, closeHandler);
        addEventListener(Event.CONNECT, connectHandler);
        addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
        addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
    }

    private function writeln(str:String):void {
        str += "\n";
        try {
            writeUTFBytes(str);
        }
        catch(e:IOError) {
            trace(e);
        }
    }

    private function sendRequest():void {
        trace("sendRequest");
        response = "";
        writeln("GET /");
        flush();
    }

    private function readResponse():void {
        var str:String = readUTFBytes(bytesAvailable);
        response += str;
    }

    private function closeHandler(event:Event):void {
        trace("closeHandler: " + event);
        trace(response.toString());
    }

    private function connectHandler(event:Event):void {
        trace("connectHandler: " + event);
        sendRequest();
    }

    private function ioErrorHandler(event:IOErrorEvent):void {
        trace("ioErrorHandler: " + event);
    }

    private function securityErrorHandler(event:SecurityErrorEvent):void {
        trace("securityErrorHandler: " + event);
    }

    private function socketDataHandler(event:ProgressEvent):void {
        trace("socketDataHandler: " + event);
        readResponse();
    }
}

答案 2 :(得分:0)

关键是收听事件SocketIOErrorEvent.IO_ERROR对象。如果您指的是立即拒绝连接的情况,则会立即触发此事件 。事实上,它可以被触发得如此之快,以至于你会错过它,除非你按照正确的顺序做事(如下所示):

// first create the unconnected socket, and add the listener
// you *must* add the listener *before* connecting the socket
//
var mySocket = new Socket();
mySocket.addEventListener(IOErrorEvent.IO_ERROR, function(event:IOErrorEvent):void {
    // called when error occurrs
    trace("ioErrorHandler: " + event);
});
mySocket.addEventListener(flash.events.Event.CONNECT, function(event:Event):void {
    // handle a successful connection here
    //...
});

// now initiate the connection to port 80 on "server.example.com"   
mySocket.connect( 'server.example.com', 80 );

注意:此方法基于超时。如果服务器返回明确的“连接拒绝”响应,则在收到响应时立即发生IO错误事件。

超时仅适用于服务器在较长时间内未返回任何内容的情况。某些服务器/防火墙配置实际上会静默地丢弃数据包而不是返回“拒绝连接”,这可能会发生。发生这种情况时,客户端(在本例中为Flash)将等待超时到期。当超时最终到期时,它将导致IOErrorEvent.IO_ERROR事件,如您所料。

默认套接字超时与平台有关,但总是相当长(约20-30秒或更长)。 Socket.timeout属性是在Flash Player版本10和Air 1.0中引入的。据我所知,在Flash Player 10之前无法使用ActionScript调整套接字超时。

祝你好运!

---编辑:如果仍然无法正常工作,请继续阅读---

您还应该熟悉Flash播放器查找(并要求)套接字策略文件的方式。丢失或损坏的套接字策略文件有时会产生看起来像套接字等待超时的行为。引自this Adobe Document

  

默认情况下,即使是套接字,也会禁用对套接字和XML套接字连接的访问   您要连接到的是与SWF文件位于同一域中。您可以允许套接字级别   通过从以下任何位置提供套接字策略文件进行访问:

     
      
  • 端口843(主策略文件的位置)
  •   
  • 与主套接字连接相同的端口
  •   
  • 与主套接字连接不同的端口
  •   

这意味着,除非您之前使用Security.loadPolicyFile()加载了策略文件,否则当您最初尝试将套接字连接到服务器时,Flash将首先尝试解析策略文件。在某些情况下,这可能导致奇怪的连接延迟或其他意外行为。如果您认为可能遇到此问题,则应首先为flash.events.SecurityErrorEvent.SECURITY_ERROR添加一个监听器。