2015-05-19 28 views
0

我正在開發一個使用服務器套接字的Firefox附加組件,並且我發現可以使用相同地址打開服務器套接字:港口,這很奇怪。我用netstat檢查過,我感到震驚。Firefox sdk addon:非常奇怪,我可以在同一地址上打開2個服務器套接字:端口

此事的行爲是,第一個打開的服務器套接字接受所有連接,然後,當它關閉時,第二個接受新的連接。

更有趣的是,如果我用java打開服務器套接字,那麼我無法用firefox插件打開另一個服務器套接字。所以,應該有一些標誌允許這個問題,但是我在sdk API中找不到任何東西來避免這個問題。

我做的Windows 7

下的測試,我想檢測服務器套接字已經打開,瞬間。我不想打開一個客戶端套接字來檢查這一點。有任何想法嗎?

這裏是我打開插座,並不是很困難......

try 
{ 
    serverSocket = Cc["@mozilla.org/network/server-socket;1"].createInstance(Ci.nsIServerSocket); 
    serverSocket.init(listenPort, true, 100); 
    serverSocket.asyncListen(listener); 
} 
catch(error) 
{ 
    console.log(error); 

回答

0

好了,很多搜索後,我只能提供一個解決此問題的。只需測試服務器套接字是否打開。這個解決方案非常快,而且工作。下面是創建ServerSocket以避免此問題的一些代碼:

const {Cc, Ci, Cu, components} = require("chrome"); 

const gThreadManager = Cc["@mozilla.org/thread-manager;1"].getService(); 

function ServerSocket(){ 

    function checkFreePort(port, callback, error){ 
     try{   
      var bRead = false; 
      var socket_service = Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci.nsISocketTransportService); 

      // we open a socket client to test if there is a server socket listening 
      socket = socket_service.createTransport(null, 0, "127.0.0.1", port, null); 
      socket.setEventSink ({ 
       onTransportStatus : function(transport, status){ 
        if (status == nsISocketTransport.STATUS_CONNECTED_TO) // connected 
        { 
         if (!bRead) 
         { 
          bRead = true; 
          try{ 
           socket.close(); 
          }catch(ex){ 
           console.log(ex); 
          } 
          // connected to the server socket, so we return error 
          error(); 
         } 
        } 
       } 
      }, gThreadManager.mainThread); 

      // we put a timeout to avoid the block of the extension forever, 2 seconds should be enougth for localhost 
      // actually tests shows that the socket replies instantly if there is no server socket listening on the onInputStreamReady 
      socket.setTimeout(0, 2000); 

        var input = socket.openInputStream(Ci.nsITransport.OPEN_BLOCKING,0,0); 


      input.asyncWait({ 
       onInputStreamReady: function(input) { 
        try 
        { 
         // if there is no server socket listening, we get onInputStreamReady and reading the stream will throw an error... 

         if (bRead) // we detected the connection before, so we have finished 
          return; 
         var sin = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream); 
         sin.init(input); 
         sin.read(1); 
         bRead = true; 
         // we read something, code should never execute this because we must be connected before and we have controlled it 
         // but... just in case... 
         error(); 

        } 
        catch(ex) { 
         // error reading, the socket can't connect, so it is ok for us 
         bRead = true; 
         callback(); 
        }   
        finally 
        { 
         sin.close(); 
         input.close(); 
        } 
       } 
      }, 0, 0, gThreadManager.mainThread); 
     } 
     catch(error2) 
     { 
      console.log("Unexpected error: " + error2); 
      error(); 
     } 

    } 

} 

ServerSocket.prototype = { 
    listen: function(port, listener, errorCallback){ 
     checkFreePort(port, function(){ 
      serverSocket.init(port, true, 100); 
      serverSocket.asyncListen(listener); 
     }, errorCallback); 
    } 
} 


var listener = { 
     onSocketAccepted: function(serverSocket, clientSocket) { 
      console.log("Accepted connection on " + clientSocket.host + ":" + clientSocket.port); 

      // do stuff 

     } 
    }; 


var server = new ServerSocket(8080, listener, function(){ 
    console.log("Error creating server socket"); 
}); 
相關問題