Investigating the Servlets I've created a simple chat and tested it on local IP - everything works. But when I tried to test it through the real network the connection refused - java.net.ConnectException: Connection refused: connect
. Is the reason in Dynamic IP which I have, or additional settings are needed? Thanks in advance!
Server:
/**
* Created by rnd on 7/4/2017.
*/
import java.io.*;
import java.net.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class VerySimpleChatServer {
ArrayList clientOutputStreams;
public static void main (String[] args) {
new VerySimpleChatServer().go();
}
public void go() {
clientOutputStreams = new ArrayList();
try {
ServerSocket serverSock = new ServerSocket(5000);
while(true) {
Socket clientSocket = serverSock.accept();
Charset charset = StandardCharsets.UTF_8;
OutputStreamWriter osw = new OutputStreamWriter( clientSocket.getOutputStream(), charset );
PrintWriter writer = new PrintWriter( new BufferedWriter( osw ) );
// PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
writer.println("Welcome to the chat 7 kids.... Семеро Козлят");
writer.flush();
clientOutputStreams.add(writer);
Thread t = new Thread(new ClientHandler(clientSocket));
t.start() ;
System.out.println("got a connection");
}
} catch(Exception ex) {
ex.printStackTrace();
}
} // Закрываем go
public class ClientHandler implements Runnable {
BufferedReader reader;
Socket sock;
public ClientHandler(Socket clientSocket) {
try {
sock = clientSocket;
InputStreamReader isReader = new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8);
reader = new BufferedReader(isReader);
} catch(Exception ex) {ex.printStackTrace();}
} // Закрываем конструктор
public void run() {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println("read " + message);
tellEveryone(message);
} // Закрываем while
} catch(Exception ex) {ex.printStackTrace();}
} // Закрываем run
} // Закрываем вложенный класс
public void tellEveryone(String message) {
Iterator it = clientOutputStreams.iterator();
while(it.hasNext()) {
try {
PrintWriter writer = (PrintWriter) it.next();
writer.println(message);
writer.flush();
} catch(Exception ex) {
ex.printStackTrace();
}
} // Конец цикла while
} // Закрываем tellEveryone
} // Закрываем класс
Client:
/**
* Created by rnd on 7/4/2017.
*/
import java.io.*;
import java.net.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleChatClient {
JTextArea incoming;
JTextField outgoing;
BufferedReader reader;
PrintWriter writer;
Socket sock;
public static void main(String[] args) {
SimpleChatClient client = new SimpleChatClient();
client.go();}
public void go(){
JFrame frame = new JFrame("Ludicrously Simple Chat Client");
JPanel mainPanel = new JPanel();
incoming = new JTextArea(15,50);
incoming.setLineWrap(true);
incoming. setWrapStyleWord (true) ;
incoming.setEditable(false);
JScrollPane qScroller = new JScrollPane(incoming);
qScroller. setVerticalScrollBarPolicy (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) ;
qScroller. setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS) ;
outgoing = new JTextField(20);
JButton sendButton = new JButton("Send") ;
sendButton.addActionListener(new SendButtonListener());
mainPanel.add(qScroller);
mainPanel.add(outgoing);
mainPanel.add(sendButton);
setUpNetworking();
Thread readerThread = new Thread(new IncomingReader());
readerThread.start();
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
frame.setSize(800,500);
frame.setVisible(true);
}
private void setUpNetworking() {
try {
sock = new Socket("178.165.87.221", 5000);
InputStreamReader streamReader = new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8 );
reader = new BufferedReader(streamReader);
Charset charset = StandardCharsets.UTF_8;
OutputStreamWriter osw = new OutputStreamWriter( sock.getOutputStream(), charset );
writer = new PrintWriter( new BufferedWriter( osw ) );
// writer = new PrintWriter(sock.getOutputStream());
System.out.println("networking established");
} catch (IOException ex) {
ex.printStackTrace();}
}
public class SendButtonListener implements ActionListener {
public void actionPerformed (ActionEvent ev) {
try {
writer.println(outgoing.getText());
writer.flush();
} catch(Exception ex) {
ex.printStackTrace();
}
outgoing. setText ("") ;
outgoing.requestFocus () ;}
}
public class IncomingReader implements Runnable{
@Override
public void run() {
String message;
try{
while((message=reader.readLine())!=null ){
System.out.println("read " + message);
incoming.append(message + "\n");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
If you really have a dynamic ip, you can get yourself a freedns domain (and add a firewall exception), but most probably you're behind NAT. To make it work you need multiple things:
Still, get a freedns domain and setup automatic ip address updateAs it appears, most NATs are Port-restricted cone NATs, that is, they drop incoming UDP packets from a peer until you send a packet to that peer. Besides, NAT UDP mappings you create by sending a packet expire in around 60 seconds, which is much less than for TCP mappings.
All this makes pure p2p messaging impossible for parties behind NAT. To join a p2p network you still need to exchange a few packets via a public server (e-mail or another Instant messaging provider). There's the library "ice4j" that can produce and parse these packets (SDP) and then create java socket wrappers for direct connections.
And even if two peers save each other's addresses to connect directly in the future, the addresses will eventually expire due to dynamic ip (usually 24h).