首页 文章

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

提问于
浏览
3

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

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

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

  • 关闭

  • 连接

  • ioError

  • securityError

  • socketData

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

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

3 回答

  • 0

    如何使用add <img src='http://target:port/' onerror='noconnect' /> 捕获连接错误?

  • 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();
        }
    }
    
  • 0

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

    // 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 );
    

    注意:此方法不基于超时 . 如果服务器返回明确的"connection refused"响应,则在收到响应时将立即发生IO错误事件 .

    超时仅适用于服务器在较长时间内未返回任何内容的情况 . 某些服务器/防火墙配置实际上会以静默方式丢弃数据包而不是返回"connection refused",这可能会发生这种情况 . 发生这种情况时,客户端(在本例中为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 添加一个侦听器 .

相关问题