首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android上的Java套接字,通过3G互联网全球ip连接

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

Stack Overflow用户
提问于 2013-03-11 03:22:06
回答 2查看 6K关注 0票数 2

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

我可以使用我的代码创建一个ServerSocket,并通过同一设备上的另一个套接字连接到它(一个设备上只有一个客户端的'echo‘示例可以很好地工作)我已经在同一wifi上使用了两个IP地址(192.168...)但是,使用3G连接使用internet ip地址连接远程客户端的任何尝试都会失败,并显示

代码语言:javascript
复制
java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out)

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

代码语言:javascript
复制
    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();
        }
    }

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

代码语言:javascript
复制
        while (running) {
            GuestConnect ssc = new GuestConnect(_mainServer.accept());
            ssc.setListener(this);
            ssc.startConnection();

            _clientSockets.add(ssc);

            performGuestAdded("bra!");
        }

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

通信服务器端是由本地客户端回调和发送消息给我的所有客户(我仍在做这部分工作,它还没有真正完成,但我不认为它与我的问题相关):

代码语言:javascript
复制
public void onMessageReceived(TBTGuestConnect sender, String message) {
    for(TBTGuestConnect guestConnect : _clientSockets)
        if(guestConnect != sender)
            guestConnect.sendMessage(message);
}

客户端被存储为'GuestConnect‘对象,下面是我设置它们的方式(GuestConnect.java):

代码语言:javascript
复制
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):

代码语言:javascript
复制
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());

    }
}

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

代码语言:javascript
复制
    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;
    }

然后,我可以通过此方法发送一条消息:

代码语言:javascript
复制
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地址在技术上有什么不同?

EN

回答 2

Stack Overflow用户

发布于 2013-03-27 04:34:05

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

当谈到3g网络时,看看这里的Could I connect to my iphone using 3g ip?和这里的ServerSocket accept() not accepting connections on Android。所以很有可能这是不可能的

票数 1
EN

Stack Overflow用户

发布于 2014-11-18 20:45:54

不知道这对你是否重要,但在我们国家,大多数3G帐户都被ISP阻止进入连接。你必须申请才能解封端口。有些ISP不会解除屏蔽,有些则会。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15326450

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档