Problems with chat sockets with NO-IP host

Asked

Viewed 1,026 times

4

Well, first of all, I’ve searched a lot of sites, including here, how to do this. I tested codes and modified but still, I kept getting errors.

The problem is the sockets to make the connection. I have no idea how to use them, and I need to create a program that works as a server/client. It will send something like 5 Strings, to another program that will do some reorganizations and send Strings to another server/client and return more Strings to the first, basically it will be a Chat with a Server, one Chat.jar and a Servidor.jar.

I’d like to do the Servidor.jar work on a computer with no-ip installed.

Here’s the code I have at the moment:

Socket clientSocket = null;
BufferedReader inputLine;
PrintStream os = null;
BufferedReader is = null;
InetSocketAddress addr = new InetSocketAddress("servidor.ddns.net", 15980);
try {
    ServerSocket serverSocket = new ServerSocket(15980);
    clientSocket = serverSocket.accept();
    clientSocket = new Socket("servidor.ddns.net", 15980);
    System.out.println("Connected");
    inputLine = new BufferedReader(new InputStreamReader(System.in));
    os = new PrintStream(clientSocket.getOutputStream());
    is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    serverSocket.close();
} catch (UnknownHostException e) {
    System.err.println("Don't know about host");
} catch (IOException e) {
    System.err.println("Couldn't get I/O for the connection to the host \nServer must be down! NOOO!!");
}

In a more illustrative way, it would be something like this:

Server/Client¹ ---> Server/Client Main ----> Server/Client²

Afterward...

Server/Client² ---> Server/Client Main ----> Server/Client¹

The main Server/Client would be the Servidor.Jar and the others, Chat.jar.

Using a code similar to this code from above, I only received the message from "IOException e" and in other ways, I was getting something like "Connect: refused connect".

Well... in short, I need to send several strings, while I can still receive strings. I don’t know how to explain it properly or how to ask, I’m totally lost. I hope you understand.

NOTE: The code of the rest of the program is done. Only this is missing.


This part of the code is new and already working normal, now only left a problem, I wanted to change 127.0.0.1, for an on-ip host connection, for example: meuservidor.ddns.net

Can you do that? If so, how?

Socket cliente = new Socket("127.0.0.1", 12342);
System.out.println("O cliente conectou ao servidor");
ObjectOutputStream dados = new ObjectOutputStream(cliente.getOutputStream());
// O código dessa forma está funcionando
dados.writeUTF("Projeto");
dados.writeUTF("Outra Mensagem");
dados.writeUTF("Projeto");

dados.flush();
cliente.close();

This is what appears when I change localhost to "meuservidor.ddns.net" using this port: 12342

Exception in thread "main" java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at calc.cliente.main(cliente.java:10)

The solution has to be something that does not involve releasing ports on the firewall/router.

  • Eduardo. I added some information about your mistake at the end of my reply. Let’s go.

1 answer

5

Your server code is well forwarded. But it seems to me that your confusion lies in how it works. I will try to clarify.

You need to first understand the Socket distributed communication model: think of a socket as a channel that connects two processes (in this case, two Jvms), whether they are on two separate machines or not. For the network structure that we use from where I am aware, a machine is identified by its IP and a process within a machine is identified by a PORT. So, if you want to create in JAVA a software that "listens" on port 7777 (a server) and wait for external communication, you will use the Serversocket object:

ServerSocket servidor = new ServerSocket( 7777 );
Socket cliente = servidor.accept();
// Parei pra esperar...

In this case, when the code is executed, the servidor.accept() will stop and wait for a connection. Now you want another software (i.e., another class to run separately) to connect to send messages. Basically you need this:

Socket cliente = new Socket( "127.0.0.1", 7777 );

This code when executed will open the channel with the server (as long as it is running on the same machine (IP = 127.0.0.1). If you want another machine just change the IP. Only now you have a channel, and need to pass things inside it. In the case of Java Socket, you have a two-way route, that is, one going from the client to the server and the other going from the server to the client. Each such path in Java is encapsulated by the Stream class objects (which are nothing less than a sequence of bytes).

As in your problem you want your server to receive Strings, right after the channel is opened, you need to take the Input Stream (i.e., arrival) and read:

InputStream ins = cliente.getInputStream();
ObjectInputStream objIn = new ObjectInputStream(ins);
Object msg = objIn.readObject();

I used here a ObjectInputStream for easy reading of any channel object. You can continue using your BufferedReader. Already on the client side, to send a message you need something like this:

OutputStream outs = cliente.getOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream( outs );
objOut.writeObject( "HELLOOOOO" );

That’s fundamentally it. The client uses the output channel (Outputstream) on its Socket side to send an object, which is the "HELLOOOOO" String. Notice that your object possession server msg can do whatever you want and then send back to the customer (using your Outputstream).

In order for the server to communicate with another software, it will need to create another Socket. And then the pattern is the same: either he expects a new connection, or he tries to open the connection with someone who is already waiting.

Other very common cases: (1) so that your server can receive multiple messages from the same client, a loop on readObject can help; (2) if your server needs to handle multiple clients, the best thing to do is to create a Thread for each customer, but there’s another 500.

Finally, I hope you understand this concept, because it is fundamentally the same for any network connection we use today: web, torrent, game, database... everything. Good luck!

If I can clarify anything else, ask in the comments.


About the error "java.net.Connectexception: Connection refused"; the same is normally related to the non-existence of a Serversocket available in the specified IP:PORTA. If it were the case that your HOST is not being resolved for a valid IP the error would possibly be: Unknownhostexception.

So I suggest you do two checks: (1) is your server really running? (it may sound silly, but since you are testing more than one client, it may be that when you close the first connection your server has closed) ; (2) your HOST "meuservidor.ddns.net" is actually being resolved to the IP of the machine the server is running on?

For example: when I ping to my machine name, the expected response is more or less like this PING minha_maquina (127.0.1.1). When I do the same for Google: PING google.com (173.194.42.163). In case, you have to see if your PING meuservidor.ddns.net resolves to the IP of the machine where your server software is running.

  • I’m working here on the code, and I’m already editing the topic on it, but for now it’s working just that with localhost, how would I use the no-ip host? I tried to exchange 127.0.0.1 for.ddns.net server (for example), and it didn’t work...

  • server.ddns.net is the same machine as localhost? If yes, then you need to check if this name is really being solved by DNS (a PING should solve). If not, then you may have some active firewall between the client and server processes!

  • In this case, it’s the same machine, but the intention is to run the program on other networks as well, so opening doors before using the program would not be very viable, and when you said "a ping should solve" was to ping the cmd, and see if the Packets can return?

  • That’s it. Ping first needs to resolve the IP name and then test if the machine responds. There are better tools to test the resolution of "trace" and "Dig" names (but I’m talking about the UNIX world). As for ports and firewalls, there are some rules for using ports of known numbers that are usually open like 80 and 8080. The problem is when they are already being used.

  • The ping worked, but put "Socket client = new Socket("server.ddns.net", 8080);" and change the server to 8080, gave error, that would be because of the port? If so, any idea which one to use?

  • What’s the mistake? Supplement your question with the stack of exceptions for me to try to help you. Hug.

  • Okay, I edited and I made the mistake.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.