Android上的Java套接字,通过3G互联网全球ip连接

Android上的Java套接字,通过3G互联网全球ip连接,java,android,sockets,connection,ip,Java,Android,Sockets,Connection,Ip,我在Android上使用套接字时遇到问题。我对这个话题还不熟悉,所以我试着实现一个简单的聊天,把安卓手机作为另一个安卓手机的培训 我可以使用我的代码创建一个ServerSocket,并使用同一设备上的另一个套接字连接到它(一个设备上只有一个客户端的“echo”示例很好),我也在同一wifi上使用了两个IP地址(192.168…)但是,任何尝试使用3G连接使用internet ip地址连接远程客户端的尝试都会以失败告终 java.net.SocketException: recvfrom fail

我在Android上使用套接字时遇到问题。我对这个话题还不熟悉,所以我试着实现一个简单的聊天,把安卓手机作为另一个安卓手机的培训

我可以使用我的代码创建一个ServerSocket,并使用同一设备上的另一个套接字连接到它(一个设备上只有一个客户端的“echo”示例很好),我也在同一wifi上使用了两个IP地址(192.168…)但是,任何尝试使用3G连接使用internet ip地址连接远程客户端的尝试都会以失败告终

java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out)
我要做的是创建ServerSocket(ServerConnect.java):

在同一个类中,我在一个单独的线程中执行此操作以等待客户端连接:

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

            _clientSockets.add(ssc);

            performGuestAdded("bra!");
        }
它使服务器等待多个客户端连接,因此它可以在“聊天室”中承载两个以上的用户

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

客户机存储为“GuestConnect”对象,我是这样设置的(GuestConnect.java):

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

同样,在同一类中还有通信部分:

    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地址和internet ip地址之间的技术区别是什么?

我将从末尾开始,因为这更简单-本地ip地址是私有的,在您的本地网络之外无效(且不可见),本地网络之外的人无法直接访问,但您可以使用公共ip地址访问主机。因为它们不是普遍可见的,所以私有地址不是唯一的,公共ip地址是唯一的,并且(通常)从internet上的任何点都可见。关于这个问题还有很多


说到3g网络,请看这里和这里。因此,这很可能无法做到

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


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

你可能想看视频你是说在线聊天对手机不实用吗?我想知道当一条新消息传到某个频道时,你突然看到传入的消息时,
电报
是如何工作的。(如何工作?)据我所知,所有在线聊天都有服务器。服务器具有公共IP地址,因此可以从客户端启动TCP连接以发送消息。服务器向消息接收方发送通知,以便接收方可以启动到服务器的TCP连接并获取消息。通知本身是一个有点不同的情况,它可以通过几种类似的方式完成。一种方法是让客户端保持与(例如)谷歌的永久连接,另一种方法是定时pol谷歌服务器。在这两种情况下,客户端都会启动TCP连接。我不认为
电报
(或类似的)利用
谷歌的技术
来维护他们的想法。应该有一些
套接字编程
方法来解决这种情况(我的意思是,当你想通知电话时)。客户端可以轮询服务器:
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();
   }
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 !");
}