【问题标题】:How to connect to a Java TCP server socket having Public IP From Android Tcp Client Socket?如何从 Android Tcp 客户端套接字连接到具有公共 IP 的 Java TCP 服务器套接字?
【发布时间】:2015-03-22 17:23:52
【问题描述】:

我的工作地点有两个真实 IP 地址 220.xx.xxx.xxx。我尝试制作一个简单的 java tcp 服务器程序和 android tcp 客户端程序。 android 客户端在以下情况下可以正常工作:

  1. 服务器和模拟器程序在同一台电脑上。
  2. 一台具有真实 IP 地址模拟器的 PC 中的服务器位于另一台具有真实 IP 地址的 PC 中。
  3. 服务器和模拟器都在同一台电脑或不同电脑或设备的专用网络下。

在以下情况下不起作用:

  1. 客户端是一个有wifi或3g网络的智能手机,服务器有不同网络的真实IP地址。
  2. 客户端是一个在wifi连接设备上运行的模拟器,服务器有一个真实的IP地址。

那么,如何从 Android Tcp 客户端套接字连接到具有公共 IP 的 Java TCP 服务器套接字?我不认为在这里粘贴代码真的很有必要。但是,如果有人问我可以提供。 根据我在互联网上的搜索,有些人提供了在服务器端配置路由器的建议。这在我看来有点烦人。如果我运行一个网络服务器,它可以从任何地方任何地方访问。 此处包含的代码: 服务器端:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.*;

public class Server {

    private static ServerSocket serverSocket;
    private static Socket clientSocket;
    private static InputStreamReader inputStreamReader;
    private static BufferedReader bufferedReader;
    private static OutputStreamWriter outputStreamWriter;
    private static BufferedWriter bufferedWriter;
    private static PrintWriter printWriter;
    private static String message;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            System.out.println(InetAddress.getLocalHost());
            serverSocket = new ServerSocket(4444); // Server socket

        } catch (IOException e) {
            System.out.println("Could not listen on port: 4444");
        }

        System.out.println("Server started. Listening to the port 4444");

        while (true) {
            try {

                clientSocket = serverSocket.accept(); // accept the client connection
                System.out.println("connection initiated");

                DataInputStream din = new DataInputStream(clientSocket.getInputStream());

                DataOutputStream dout= new DataOutputStream(clientSocket.getOutputStream());

                String msg = din.readUTF();
                System.out.println(msg);

                dout.writeUTF("hello from server");
                System.out.println("sent to client");



                clientSocket.close();

            } catch (IOException ex) {
                System.out.println("Problem in message reading "+ex);
            }
        }
    }

}

客户端:

package com.example.client;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

 TextView textResponse;
 EditText editTextAddress, editTextPort; 
 Button buttonConnect, buttonClear;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  editTextAddress = (EditText)findViewById(R.id.address);
  editTextPort = (EditText)findViewById(R.id.port);
  buttonConnect = (Button)findViewById(R.id.connect);
  buttonClear = (Button)findViewById(R.id.clear);
  textResponse = (TextView)findViewById(R.id.response);

  buttonConnect.setOnClickListener(buttonConnectOnClickListener);

  buttonClear.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    textResponse.setText("");
   }});
 }

 OnClickListener buttonConnectOnClickListener = 
   new OnClickListener(){

    @Override
    public void onClick(View arg0) {
     MyClientTask myClientTask = new MyClientTask(
       editTextAddress.getText().toString(),
       Integer.parseInt(editTextPort.getText().toString()));
     myClientTask.execute();
    }};

 public class MyClientTask extends AsyncTask<Void, Void, Void> {

  String dstAddress;
  int dstPort;
  String response = "";

  MyClientTask(String addr, int port){
   dstAddress = addr;
   dstPort = port;
  }
  private PrintWriter printwriter;
  private InputStreamReader inputStreamReader;
  private BufferedReader bufferedReader;
  @Override
  protected Void doInBackground(Void... arg0) {

   Socket socket = null;

   try {
    socket = new Socket(dstAddress, dstPort);

    DataInputStream din = new DataInputStream(socket.getInputStream());
    DataOutputStream dout = new DataOutputStream(socket.getOutputStream());

    dout.writeUTF("hello from client");

    response="sent to serve;r";

    String msg = din.readUTF();
    response+=msg;

    socket.close();

   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    response = e.toString();
   }
   return null;
  }

  @Override
  protected void onPostExecute(Void result) {
   textResponse.setText(response);
   super.onPostExecute(result);
  }

 }

}

【问题讨论】:

  • 你认为什么是“真实IP”?您是否将路由器的互联网 ip 与您的计算机从路由器获得的本地 ip 混淆了?
  • 很遗憾您没有在帖子中提出问题。如果客户端也有 Internet 连接并使用服务器的 Internet ip,则 Android 客户端可以与 Internet 上的服务器连接。就这样。在您的“不起作用 1”中,您同时提到了 wifi 和 3G。这是不可能的。因为他们不同,所以对他们进行不同的威胁。
  • "你认为什么是'真实IP'?" --- 答案:公共 IP 地址:如果网络服务器在其上运行,则可以从 Internet 的任何地方访问。 “您是否将路由器的互联网 ip 与您的计算机从路由器获得的本地 ip 混淆了?” --- 回答:不,我不是。我还提到了以 3 位数字开头的 IP 地址。它不是本地或私有 IP 地址。我很确定我没有把它弄混
  • “很遗憾你没有把问题放在你的帖子里。” ——现已编辑。不起作用部分几乎可以解释问题。没想到有些人可能理解有问题。 "
  • “如果客户端也有互联网连接并使用服务器的互联网IP,Android客户端可以连接互联网上的服务器。”--这是什么意思?使用服务器的互联网 ip?当它不起作用时,我非常清楚地表明android客户端和服务器位于不同的网络上。如果你不明白,请再次阅读问题。如果服务器有真实的 IP 地址并且安卓客户端在 wifi 或 3g 网络中,他们为什么使用相同的互联网?

标签: java android sockets networking tcp


【解决方案1】:

我刚刚将端口号从 4444 更改为 6667,现在它在任何地方都可以使用。我认为端口 4444 没有在其他地方使用,因为该程序在本地网络上运行

【讨论】:

    【解决方案2】:

    要使TCP connections 在真实设备上工作,您需要提供公共托管域的URLlocalhost 或本地网络 URL 仅适用于同一本地网络上 a PC 上的 an emulator

    参考资料:

    1. Emulator Networking.

    2. How to connect to my http://localhost web server from Android Emulator in Eclipse

    3. Accessing localhost:port from Android emulator

    4. Calling web service from android device

    5. Connect an Android Device To a Web Service on Local Host

    6. How can I access my localhost from my Android device?

    7. How to browse localhost on android device?

    【讨论】:

    • 对不起!我刚刚通过将端口号从 4444 更改为 6667 成功运行了程序。虽然我不知道为什么,因为在 4444 上它只能在本地网络上运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 2015-10-04
    • 1970-01-01
    • 2012-11-15
    • 2012-03-29
    • 2018-05-24
    • 2013-05-14
    相关资源
    最近更新 更多