Oi! Faz pouco tempo que comecei a tentar aprender programação com sockets no Java e estou tendo algumas dificuldades. Eu procurei um pouco sobre o assunto e tentei montar o programa, que funciona perfeitamente com o localhost e com conexões na rede local. Mas quando tento fazer a conexão com um computador fora da rede, a conexão não ocorre. Tentei utilizar alguns recursos de UPnP, mas ainda não consegui fazer funcionar. Provavelmente, estou usando de forma errada
Esse é o código do servidor:
package com.gados.net;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import com.dosse.upnp.*;
public class Server implements Runnable {
private ServerSocket ss;
private DataOutputStream out;
private DataInputStream in;
private InetAddress ip;
private int port;
public int maxClients = 2, minClients = 2;
private ArrayList<Socket> clients = new ArrayList<>();
private ServerListener listener;
public Thread thread;
public boolean start = false;
private boolean open = true;
public Server(int port, ServerListener listener) {
thread = new Thread(this);
this.listener = listener;
this.port = port;
try {
ss = new ServerSocket(port);
this.ip = ss.getInetAddress();
ss.setSoTimeout(100000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void listenPort() {
try {
if (UPnP.isUPnPAvailable()) { //is UPnP available?
if (UPnP.isMappedTCP(port)) { //is the port already mapped?
System.out.println("UPnP port forwarding not enabled: port is already mapped");
} else if (UPnP.openPortTCP(port)) { //try to map port
System.out.println("UPnP port forwarding enabled");
} else {
System.out.println("UPnP port forwarding failed");
}
} else {
System.out.println("UPnP is not available");
}
System.out.println("listening to port: " + port);
Socket server = ss.accept();
System.out.println("Conncted to " + server.getRemoteSocketAddress());
in = new DataInputStream(server.getInputStream());
System.out.println("message from " + server.getRemoteSocketAddress() + ": " + in.readUTF());
out = new DataOutputStream(server.getOutputStream());
clients.add(server);
System.out.println("connection stablished with " + server.getLocalSocketAddress());
// out.writeUTF("ping");
listener.clientConnected(in, out);
} catch(SocketTimeoutException e) {
System.out.println("timed out!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void kickClient(Socket client) throws IOException {
for(int i = 0; i < clients.size(); i++) {
if(!client.equals(clients.get(i))) continue;
clients.get(i).close();
clients.remove(i);
break;
}
}
private void closeServer() throws IOException {
for(Socket s : clients) {
kickClient(s);
}
ss.close();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(open) {
while(!start || clients.size() < minClients || clients.size() <= maxClients && !start) {
listenPort();
}
listener.receivedInput(in);
listener.writeOutput(out);
}
try {
closeServer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Esse é o código do cliente:
package com.gados.net;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public class Client implements Runnable{
private Socket socket;
private DataOutputStream out;
private DataInputStream in;
private String ip;
private int port;
private boolean open = true;
private ClientListener listener;
public Thread thread;
public Client(String ip, int port, ClientListener listener) {
thread = new Thread(this);
this.ip = ip;
this.port = port;
this.listener = listener;
}
private void connect() {
try {
System.out.println("Trying to connect to " + ip + " on port " + port);
socket = new Socket(ip, port);
System.out.println("connected to " + ip + " on port " + port);
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
System.out.println("server return: " + in.readUTF());
listener.connected(in, out);
} catch (IOException e) {
// TODO Auto-generated catch block
listener.unknownHost();
e.printStackTrace();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
while(open) {
if(socket == null) connect();
listener.receivedInput(in);
listener.writeInput(out);
}
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Eu estou iniciando o servidor e o cliente assim:
if(JOptionPane.showConfirmDialog(mainWindow, "server?") == 0) {
int port = Integer.parseInt(JOptionPane.showInputDialog("port:"));
Server sv = new Server(port, new ServerIn());
sv.thread.start();
sv.start = true;
} else {
String ip = JOptionPane.showInputDialog("IP:");
int port = Integer.parseInt(JOptionPane.showInputDialog("port:"));
Client cl = new Client(ip, port, new ClientIn());
cl.thread.start();
}
Os parâmetros “ServerListener” e “ClientListener” são interfaces com métodos que ainda não estão fazendo nada.
(Se faltou alguma informação importante, me avise. Eu sei bem pouco mesmo sobre o assunto)
Algém pode me ajudar? Obrigado!