4

これに非常にこだわっているので、あなたが与えることができるどんな助けにも感謝します!

Android アプリとマルチソケットJava サーバーの 2 つのプログラムがあります。Android アプリは、最初にサーバーへのアウトバウンド接続 (ポート 21) を確立し、次にサーバーからのインバウンド接続 (ポート 1025) を受け入れます。一貫性を保つために、接続が確立される方向に関係なく、常に Android アプリをクライアント、Java アプリをホストと呼びます。

プログラムはローカル ネットワーク上で完全に動作し、Android フォンがローカル サーバー IP に接続されている192.168.1.103か、サーバーをホストしている PC 上のエミュレーターが に接続されています10.0.2.2

ただし、ローカル イントラネットの外に移動すると、ポート 21 で Android->server 接続を確立できますが、サーバーからポート 1025で電話に接続しようとするとタイムアウトします。

私が説明しているもののリスト:

  1. Android エミュレーターでポート 1025 がリダイレクトされる
  2. Windows (Win 7 サーバー ホスト) ファイアウォールが無効になっている、他の既知のファイアウォールが無効になっている
  3. 着信接続リスナーはメイン スレッド上にありません (SDK 2.1 は重要ではありません)。
  4. ルーターのポート 21 と 1025 が転送されています

テストとその結果のリスト:

  1. ローカル ネットワーク上のエミュレーター/Android フォン/リモート ネットワーク上の Android フォンからサーバーのパブリック IP (ルーターが存在する) に接続する - サーバー - > 電話接続の確立に失敗する
  2. ルーターを取り外し、エミュレーターまたはリモート Android フォンから接続する -サーバー -> 電話接続の確立に失敗する
  3. エミュレータから への接続10.0.2.2、ルータの有無にかかわらず -成功
  4. ローカル ネットワーク上の Android フォンから192.168.1.103-に接続すると成功します

最後に、いくつかのコード、サーバーの出力接続試行(このクライアントのサブスレッドは、サーバーがインバウンド接続を受信したときに既に作成されているため、コンストラクターで接続が作成されます)

OutputSocketServer(InetAddress inetAddress, int port, int count , LinkedBlockingQueue<Packet> outQueue) {
    this.outQueue = outQueue;
    SocketAddress sockaddr = new InetSocketAddress(inetAddress,port);

    try {
        outConnection = new Socket();
        System.out.println("Connecting to " + sockaddr.toString()); 
        outConnection.connect(sockaddr, timeout);
        System.out.println("Connected to port " + outConnection.getPort() + " of " +outConnection.getInetAddress().toString() + " from local port " + outConnection.getLocalPort());
        osw = new ObjectOutputStream(outConnection.getOutputStream());
    } catch (IOException e) {
        System.out.println("Output Socket Server: Could not establish outbound connection" + e.toString());
        e.printStackTrace();
    }
}

および Android クライアントの接続受け入れコードの関連部分

public void run() {
try {
        System.out.println("Listening for connection on local port " + inSocket.getLocalPort());
        this.inConnection = inSocket.accept();
        System.out.println("Accepted connection on port " + inConnection.getPort() + " from ip " + inConnection.getInetAddress().toString());
        isr = new ObjectInputStream(inConnection.getInputStream());
}
catch (Exception e) {
        System.out.println("Inbound Socket Server: " + e.toString());
    }
}

Android クライアントのスタック トレースには、SocketTimeoutException: operation timed outand for the server とだけ表示されますConnectException: connection refused: connect。その前に、クライアントの LogCat ショーListening for connection on port 1025とサーバーConnecting to /my.ip.he.re:1025

ご指導ありがとうございます。

4

1 に答える 1

4

ほとんどのワイヤレス サービスは、ルーティング不可能な RFC1918 アドレスのみをデバイスに割り当て、NAT を介して「インターネット」をルーティングします。つまり、デバイスはアウトバウンド接続を確立できますが、外部 (インバウンド) から接続することはできません。その理由の 1 つは、空き IPv4 アドレス空間が不足していることです。

あなたの投稿ではポート 21 について言及しているので、FTP が必要な場合は、パッシブ モードを使用してください。このモードでは、Android デバイスがサーバーへのデータ接続を行います。

于 2012-08-19T15:59:21.727 に答える