PDA

Ver la versión completa : [Sockets] Problema conexión Chat Java (funciona en LAN pero no en conexión Remota).



-Localhost-
23-07-2010, 21:03
Hola,

Programé un chat en java y al probarlo conectando desde un ordeador remoto me dio error: java.net.ConnectException: Connection timed out: connect. Aunque lo había probado ya en la LAN y funciona al 100%.

Sé que es posible que sea por el firewall pero creo que es más seguro que sea un problema de programación, he leido información y al parecer los protocolos de conexiones en LANs son diferentes a los protocolos de conexiones Remotas y no te estoy seguro de ese dato, ¿alguien podría confirmármelo? También se me ocurrió crearme un dominio en www.no-ip.com y hacer que el chat use esa dirección ip para conectar al servidor y no la misma dirección IP pública.

Añado también que para conectar al chat el único parámetro relevante que uso es mi IP pública.


Códigos : aquí. (http://www.mediafire.com/download.php?8aph94katnc0ok2)

hystd
26-07-2010, 00:14
Una cosa es el protocolo de aplicación y otra la topología de la red... No tienen nada que ver...

Haciendo referencia a las capas del modelo OSI y a modo de ejemplo, tendríamos por ejemplo los siguientes protocolos:

Nivel Físico: RS232, Coaxial, Fibra óptica, RadioFrecuencia, un tio montado en un burro etc...
Nivel de Enlace: Ethernet o 802.3, Wifi o 802.11, PPP, etc...
Nivel de Red: ARP, IP, X.25, ICMP, NetBEUI, etc...
Nivel de Transporte: TCP, UDP, etc...
Nivel de Sesión: SSL, NetBios, RPC, etc...
Nivel de Presentación: PSAP, SSAP, (Paso a través, o dicho de otra forma: "pillo la info, no hago nada y se la doy al siguiente nivel"), etc...
Nivel de Aplicación: HTTP, FTP, POP3, SMTP, IRC, ICQ, Telnet, etc...

En una comunicación de un sistema distribuido, al menos deben existir los 3 primeros (son OBLIGATORIOS y sin ellos no habría comunicación). Los 4 siguientes serán optativos y dependerá del uso final.

La topología de la red (local, internet, etc.), hace referencia a los 3 primeros niveles, y la comunicación es cosa suya... De forma que al programador de la aplicación le da igual que la info vaya por una fibra óptica, o que vaya un tio en un burro para llevar y traer la info. La tarea de decidir a quién, cómo y cuando la llevan a cabo la tarjeta de red del equipo (nivel de enlace) y el router (nivel de red).

En tu caso, seguramente habrás ido directamente a la capa Aplicación y habrás usado el protocolo correspondiente (o en otro caso, te habrás improvisado uno basandote en tu arquitectura cliente/servidor)... También puedes que hayas metido (o usado implícitamente, si has usado clases ya implementadas), protocolos a nivel de transporte (normalmente TCP).

Con todo esto quiero decir que, si usas por ejemplo el protocolo HTTP, o FTP, o ICQ O etc..., en tu aplicación, da igual que el servidor esté en China y el tio en su burro tenga que llevar y traer la info desde y hasta el cliente, como que el servidor esté en la habitación o sala de al lado y sea un cablecito CAT-5, o incluso en tu propia máquina local. El protocolo de aplicación es independiente de la arquitectura de la red y de su topología.

Por tanto, si lo único que has implementado es la aplicación, habrás tenido que hacer uso de algún protocolo de aplicación, y a ese protocolo le da igual lo que haya por debajo (presentación, sesión, transporte, red, enlace y físico) y de cómo se las apañen para llevar y traer la información al destinatario...

Por tanto apostaría a que es más un problema de configuración de tu router/firewall (Nivel de red).

Un saludo.

-Localhost-
26-07-2010, 13:08
Era un problema de que tenía que mapear el puerto, publiqué la duda en otro foro y me la solucionaron allí. Gracias por contestar, si quieres pongo el enlace al hilo del otro foro aquí :).

hystd
26-07-2010, 19:34
Si, ponlo, y más recomendable es que publiques tus conclusiones ;), y así podemos aprender tod@s.

Un saludo.

-Localhost-
27-07-2010, 05:30
El hilo es www.elhacker.net en este link (https://foro.elhacker.net/java/solucionado_problema_conexion_chat_javafunciona_en _lanno_en_conexion_remota-t300435.0.html). Sinceramente la única conclusión que saqué de eso es que el problema no siempre está en el código xD, me dejé un montón de tiempo buscando la manera en la que crear el socket correctamente para que conectase, y luego todo era un simple problema de puertos jeje... en fin xD.

Un saludo.

hystd
27-07-2010, 20:33
Ok! gracias por el link. Para la próxima ya sabes por donde abordar el problema (ver post anterior). Acuérdate que un protocolo de aplicación le da igual que por debajo el cliente/servidor destino esté en otro equipo dentro de una red local y nada más, o que el cliente/servidor esté en internet o que simplemente esté en tu propio equipo.

Un saludo.

-Localhost-
28-07-2010, 03:26
si, ahora esa parte está controlada, ya no me como más la cabeza pensando si el problema está en el medio en eque se transmite la información ni nada similar, que pa eso está la máquina virtual xD.

pero ahora tengo un problema al usar Threads junto con Sockets, hago bastantes códigos y todos se me traban, quiero hacer un sencillo sistema de mensajería, pero cuando no me da error, simplemente se me queda trabado como si no recibiese los mensajes, te improviso un ejemplo de lo que hago:





import java.net.*;
import java.io.*;
public class servidor extends Thread{

private Socket socket;
private ServerSocket socketServidor;
BufferedReader leerConsola = new BufferedReader(new InputStreamReader (System.in));
BufferedReader leerCliente;
BufferedWriter escribirCliente;

public Servidor (int puerto){

try{
socketServidor = new ServerSocker(puerto);
while (true){
socket = socketServidor.accept();
this.start();
}
} catch (IOException ioe) {}
}

public static void main (String args[]){ new Servidor (6789); }

public void run(){
leerCliente = new BufferedReader (socket.getInputStreamReader()));
escribirCliente = new BufferedWriter (socket.getOutputStreamReader()));
System.out.println(leerCliente.readLine());
escribirCliente.write(leerConsola.readLine());
}
}


import java.net.*;
import java.io.*;

public class Cliente extends Thread {

String ip;
int puerto;
Socket socket;
BufferedReader leerConsola = new BufferedReader (new InputStreamReader(System.in));
BufferedReader leerServidor;
BuferedWriter escribirServidor;
public Cliente (String ip, int puerto) {

this.ip = ip;
this.puerto = puerto;
try{
socket = new Socket(ip,puerto);
leerServidor = new BufferedReader (new InputStreamReader (socket.getInputStreamReader()));
escribirServidor = new BufferedWriter (new OutputStreamWriter(socket.getOutputStreamWriter()) );
this.start} catch (IOException ioe){}
}

public static void main (String args[]) { new Cliente("localhost",6789);}

public void run(){

System.out.println(leerServidor.readLine());
escribirServidor.write(leerConsola.readLine());
}

}



Si eso diese un error de compilación no importa porque el código yo lo compilo sin problema, ese lo acabo de improvisar aquí en el mismo editor de respuesta rápida del foro. Pero haciendo códigos similares los mensajes simplemente nunca llegan se envían del cliente al servidor ni vise versa, si pudieses ayudarme te lo agradecería, porque no sé muy bien como funcionan los Thread, nunca hice nada con ellos y no los comprendo del todo.

PD: este tema creo que es un poco extenso... si me pudieses ayudar por mensajería instantánea te lo agradecería porque no creo que se solucione rápido si no... xDDD mi msn es : [email protected] .

Un saludo, y gracias de antemano.

clarinetista
28-07-2010, 16:05
-Localhost-, pídelo vía mp no mails, que están prohibidos.......

hckr
28-07-2010, 21:15
Jeje clavito lo solucionastes? o me tienes que seguir utilizando de conejillo de indias? xD aunque los dos vemos que ese conejillo está mal eh? xD Descargaré uno prefabricado y será mas facil...

-Localhost-
29-07-2010, 00:10
de acuerdo clarinetista, lo siento por colocar mi mail jeje, ya si eso le mando un privado.

hckr está solucionado... escepto en tu ordenador que no chuta ni la versión que programé yo, ni algunas prefabricadas que te mandé, en tu ordenador simplemente no chuta y punto, habrá que ver si tienes las JRE instaladas y la versión de JDK que instalastes xD.

hystd
29-07-2010, 02:06
Intuyo que tu intención es hacer que el servidor sea capaz de atender varias conexiones de distintos clientes... ¿me equivoco?. Si es asi, entonces vayamos por partes...

La idea consiste en hacer que el servidor se mantenga en un bucle infinito (un while(true)), como tu tienes, esperando a que se conecte un cliente, y en tal caso, crear un nuevo hilo en el servidor, para ese cliente, es decir, instanciar una clase que herede de Thread o implemente la interfaz Runnable, cosa que no veo en ese código.

Así se me ocurre que pueden haber 3 clases: Servidor.java, Cliente.java e Hilo.java.

Hilo.java

public class Hilo implements Runnable
{
public Hilo(Socket socket)
{
...//tu constructor... con tus buffers.
}

public void run ()
{
while (true)
{
// Aqui pones el código para atender al cliente que se conecte.
// Un read del buffer de entrada y un println para mostrar los datos recibidos.
}
}
}


Ahora en la clase servidor.java, te mantienes a la espera de que se conecte un nuevo cliente, y en caso de conexión, haces una instancia (te creas un objeto), de la clase hilo.java... algo así como:

Servidor.java

public class Servidor
{
public Servidor()
{
ServerSocket miSocket = new ServerSocket(6789);

while (true)
{
// Esperamos a un cliente
Socket cliente = miSocket.accept();

//cliente conectado. Creamos un objeto de la clase hilo.java
Runnable miCliente = new Hilo(cliente);
Thread hilo = new Thread(miCliente);
hilo.start();
}
}
}


Por último, el cliente 3/4 de lo mismo... En el constructor te creas los buffers de lectura y escritura y por cada petición, te creas un nuevo hilo.

Cliente.java

public class Cliente implements Runnable
{
public Cliente(Socket socket){
//creas los buffers de lectura y escritura.
//creas un nuevo hilo para atender los datos que se reciban del socket.
Thread hilo = new Thread(this);
hilo.start();
}
public void run(){
while (true)
{
//leer del buffer de entrada
//mostrar el resultado
}
}

Bueno, más o menos sería algo así el tratamiento de hilos en java para conseguir lo que "creo" que quieres conseguir...

De todas maneras, tracear el código cuando se implementa algo, ayuda mucho en el desarrollo y en la depuración de errores.

Un saludo.

-Localhost-
29-07-2010, 03:24
Si!, es exáctamente eso lo que quería hacer, muy claro el código que planteas con muy pocas líneas y parece que me va a aclarar todo el asunto de los hilos x) (sólo lo he mirado por encima todavía pero se ve genial, bueno voy a mirarlo a fondo ahora). Muchas gracias por tus respuestas =D.

Te mandé un privado con mi msn para que me agregases =).

------------------------------------------------EDITO---------------------------------------------------------------------------------

Acabo de leer, compilar, y ejecutar el código. Me da el mismo problema por el que inicié pregunté acerca de los Thread jeje veamos estos son los códigos:

Hilo:
import java.net.*;
import java.io.*;

public class Hilo implements Runnable {

BufferedReader leerCliente;
BufferedReader leerConsola;
BufferedWriter escribirCliente;

public Hilo(Socket socket) {
try {

leerCliente = new BufferedReader(new InputStreamReader(socket.getInputStream()));
leerConsola = new BufferedReader(new InputStreamReader(System.in));
escribirCliente = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException ioe) {
}
}

public void run() {

while (true) {
try {

String mensaje = leerConsola.readLine();
escribirCliente.write(mensaje);
mensaje = leerCliente.readLine();
System.out.println(mensaje);
} catch (IOException ioe) {
}
}
}
}

Servidor:

import java.net.*;
import java.io.*;

public class Servidor {

public Servidor() {
try {
ServerSocket miSocket = new ServerSocket(6789);

while (true) {

Socket cliente = miSocket.accept();


Runnable miCliente = new Hilo(cliente);
Thread hilo = new Thread(miCliente);
hilo.start();
}
} catch (IOException ioe) {
}
}

public static void main(String args[]) {

new Servidor();
}
}

Cliente:

import java.net.*;
import java.io.*;

public class Cliente implements Runnable {

BufferedReader leerServidor;
BufferedReader leerConsola;
BufferedWriter escribirServidor;
Socket socket;

public Cliente(String ip, int puerto) {

try {

socket = new Socket(ip, puerto);
leerServidor = new BufferedReader(new InputStreamReader(socket.getInputStream()));
leerConsola = new BufferedReader(new InputStreamReader(System.in));
escribirServidor = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException ioe) {
}
Thread hilo = new Thread(this);
hilo.start();
}

public void run() {

while (true) {
try {
String mensaje = leerConsola.readLine();
escribirServidor.write(mensaje);
mensaje = leerServidor.readLine();
System.out.println(mensaje);
} catch (IOException ioe) {
}
}
}

public static void main(String args[]) {
new Cliente("localhost", 6789);
}
}

Y se bloquea, simplemente no me deja escribir en la consola ni pulsar intro ni nada, es como si los socket no sirviesen de nada y los thread sólo congelasen el programa, no lo consigo hacer bien >_<.

j8k6f4v9j
29-07-2010, 10:00
Prueba a arrancar una herramienta de monitorización de tráfico (i.e. Wireshark) para ver qué datos están viajando por la red realmente y tener así una pista de dónde está el fallo.


Salu2

-Localhost-
29-07-2010, 11:04
Bueno, el problema no es con los paquetes, sino con los Thread xD, comprobé que al cerrar la sesión algunos mensajes que haya leído pues los recibe el cliente o el servidor (depende de lo que hayas cerrado) pero antes de eso los Thread lo tienen todo bloqueado.