2

我在 Android 上使用 Sockets 时遇到问题。我是这个话题的新手,所以我尝试实现一个简单的聊天,Android 手机到另一个 Android 手机作为培训。

我可以使用我的代码创建一个 ServerSocket 并使用来自同一设备的另一个 Socket 连接到它(一个设备上只有一个客户端的“回声”示例工作正常)我已经完成了在同一个 wifi 上使用两个 IP 地址(192.168 ...),但任何尝试使用 3G 连接使用互联网 IP 地址连接远程客户端的尝试都失败了

java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out)

我所做的是,创建 ServerSocket (ServerConnect.java) :

    private ServerSocket _mainServer = null;

    private void initServer() {

        try {
                        //port I use here is arbitrary: 8081
            _mainServer = new ServerSocket(CONNECT_SOCKET_PORT);
        } catch (IOException e) {
            Log.w("ServerSocket", e.toString());
            e.printStackTrace();
        }
    }

在同一个类中,在一个单独的线程中,我这样做是为了等待客户端连接:

        while (running) {
            GuestConnect ssc = new GuestConnect(_mainServer.accept());
            ssc.setListener(this);
            ssc.startConnection();

            _clientSockets.add(ssc);

            performGuestAdded("bra!");
        }

它使服务器等待多个客户端连接,因此它可以在“聊天室”中容纳两个以上的人。

通信服务器端由本地客户端回调组成,并向我的所有客人发送消息(我仍在处理这部分,它还没有真正完成,但我认为它与我的问题无关):

public void onMessageReceived(TBTGuestConnect sender, String message) {
    for(TBTGuestConnect guestConnect : _clientSockets)
        if(guestConnect != sender)
            guestConnect.sendMessage(message);
}

客户端存储为“GuestConnect”对象,这是我设置它们的方式(GuestConnect.java):

public class GuestConnect {


   private StringBuilder _currentMessage;
   private BufferedReader _is;
   private PrintStream _os;
   private Socket _clientSocket = null;

   private String _hostname;

   private boolean _running = false;

   public GuestConnect(String hostname) {
    _hostname = hostname;

    _currentMessage = new StringBuilder();
   }

clientSocket 初始化(仍然是 GuestConnect.java):

private void initSocket() {

    if(_clientSocket==null)
    {
        // Try to open a server socket on given port
        // Here is the fail when I called it from another device
        try {
            _clientSocket = new Socket(_hostname, ServerConnect.CONNECT_SOCKET_PORT);
        } catch (IOException e) {
            Log.w("GuestSocket", e.toString());
        }
    }

    // Create a socket object from the ServerSocket to listen and accept
    // connections.
    // Open input and output streams
    try {
        _is = new BufferedReader(new InputStreamReader(_clientSocket.getInputStream()));
        _os = new PrintStream(_clientSocket.getOutputStream());


    } catch (IOException e) {
        Log.w("GuestSocket", e.toString());

    }
}

同样,在同一个班级中,有交流部分:

    initSocket();

    _running = true;

    performConnectionStarted();
    try {
        while (_running) {
            String received = _is.readLine();
            _currentMessage.append(received);
            if (received.contains(ServerConnect.CONNECT_SOCKET_MESSAGE_END)) {
                String finalMsg = _currentMessage.toString().substring(0, _currentMessage.lastIndexOf(ServerConnect.CONNECT_SOCKET_MESSAGE_END));
                performMessageReceived(finalMsg);
                _currentMessage.setLength(0);
            }

        }
    } catch (IOException e) {
        Log.w("GuestSocket", e.toString());
        performError(e);
    } finally {

        try {
            _os.close();
            _is.close();
            _clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
            performError(e);
        }

        _clientSocket = null;
    }

然后我可以通过这种方法发送消息:

public void sendMessage(String toSend) {
    if (_running)
        _os.println(toSend+ServerConnect.CONNECT_SOCKET_MESSAGE_END);
    else
        throw new IllegalStateException("Send message : Connection isn't started !");
}

所以问题是,我应该怎么做才能使用全球互联网 IP 地址使其工作?

更一般地说,相同的wifi本地IP地址和互联网IP地址之间的技术区别是什么?

4

2 回答 2

1

不知道这对您是否重要,但在我们国家,大多数 3G 帐户都被 ISP 阻止传入连接。您必须申请解锁端口。有些 ISP 不会解除对它们的阻止,有些会。

当我想将我的 DVR 与 3G 调制解调器连接时发现了这一点。

于 2014-11-18T12:45:53.530 回答
1

我将从最后开始,因为它更容易 - 本地 IP 地址是私有的,它在您的本地网络之外无效(并且不可见),本地网络之外的人无法直接访问它,但您可以使用公共访问主机ip地址。因为它们不是普遍可见的私有地址不是唯一的,所以公共 IP 地址是唯一的并且(通常)从 Internet 上的任何点都可见。关于这个主题的更多信息http://en.wikipedia.org/wiki/Network_address_translation

当涉及到 3g 网络时,请看这里我可以使用 3g ip 连接到我的 iphone 吗?在这里ServerSocket accept() 不接受 Android 上的连接。所以很可能无法完成

于 2013-03-26T20:34:04.640 回答