2

I have problems using Sockets on Android. I'm new to this topic so I try to achieve a simple chat, Android phone to another Android phone as a training.

I can use my code to create a ServerSocket and connect to it with another Socket from the same device ( An 'echo' example with only one client on one device works fine) I've done that also using two IP adresses on the same wifi (192.168...) but any tentative to connect a distant client using internet ip address using 3G connection fails with a

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

What I do is, creating the 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();
        }
    }

in the same class, in a separate thread I do this to wait for client connections :

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

            _clientSockets.add(ssc);

            performGuestAdded("bra!");
        }

it makes the server waiting for multiple client connection, so it can host more than two poeple in the 'chat room'.

The comunication server side is made from the local client callback and dispatch messages to all my guests (I'm still working on this part, its not really done yet but I don't think its relevant to my problem here) :

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

Clients are store as 'GuestConnect' objects here is how I set them (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 initialisation (still 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());

    }
}

again, in the same class there is the comunication part :

    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;
    }

I can then send a message from this method :

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 !");
}

So the question is, what should I do to make this works using global internet ip addresses ?

And more generally, what it the technical difference between same wifi local ip address and internet ip adress ?

Guian
  • 4,563
  • 4
  • 34
  • 54

2 Answers2

1

i'll start from the end because it's easier - local ip address is private, it's not valid (and not visible) out of your local network, someone out of your local network can't access it directly but you can access hosts with public ip addresses. because they are not universally visible private addresses are not unique, public ip addresses are unique and (normally) visible from any point on the internet. there's more on the subject http://en.wikipedia.org/wiki/Network_address_translation

when it comes to 3g networks take a look here Could I connect to my iphone using 3g ip? and here ServerSocket accept() not accepting connections on Android . so most probably it can't be done

Community
  • 1
  • 1
Dark
  • 864
  • 9
  • 17
  • Are you saying that online chat is not practical for phones? I wonder to know how `telegram` works when a new message post to a channel and you suddenly see the incoming message. (How does it work?) – Rzassar Oct 15 '17 at 07:37
  • As far as I know all online chats have servers. Server has a public IP address so TCP connection can be initiated from a client in order to send a message. Server sends a notification to message receiver so receiver can initiate TCP connection to server and get the message. Notification itself is a bit different case, it can be done in several similar ways. One way is for client to keep permanent connection to (for example) Google, other is to pol Google server for time to time. In both cases client initiates TCP connection. – Dark Oct 15 '17 at 14:13
  • I don't think `telegram` (or some sort of that) utilize `google's technology` to maintain their ideas. There should be some `socket programming` way out there to address such situations (I mean, when you want to notify the phone). – Rzassar Oct 18 '17 at 15:29
  • Client can poll the server: https://www.google.com.tr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=11&cad=rja&uact=8&ved=0ahUKEwj0raSHhPzWAhVBLcAKHXEKCpwQFghhMAo&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FPolling_(computer_science)&usg=AOvVaw2v9Hldf8BcoX3YCOvs0FTm – Dark Oct 19 '17 at 06:14
1

Don't know if this would be of any importance to you but in our country most 3G accounts are blocked by the ISP from incoming connections. You have to apply to unblock the ports. Some ISP's won't unblock them and some will.

Found that out when I wanted to connect my DVR with a 3G modem.