J'ai essayé d'obtenir un programme de test de réseau simple à exécuter sans résultats.
Serveur:
import Java.io.*;
import Java.net.*;
public class ServerTest {
public static void main(String[] args) {
final int PORT_NUMBER = 44827;
while(true) {
try {
//Listen on port
ServerSocket serverSock = new ServerSocket(PORT_NUMBER);
System.out.println("Listening...");
//Get connection
Socket clientSock = serverSock.accept();
System.out.println("Connected client");
//Get input
BufferedReader br = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
System.out.println(br.readLine());
br.close();
serverSock.close();
clientSock.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
Client:
import Java.io.*;
import Java.net.*;
public class ClientTest {
public static void main(String[] args) throws IOException {
final int PORT_NUMBER = 44827;
final String HOSTNAME = "xx.xx.xx.xx";
//Attempt to connect
try {
Socket sock = new Socket(HOSTNAME, PORT_NUMBER);
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
//Output
out.println("Test");
out.flush();
out.close();
sock.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
Le programme fonctionne très bien lorsque j'utilise 127.0.0.1 ou mon adresse IP interne pour le nom d'hôte. Mais chaque fois que je bascule sur mon adresse IP externe, une erreur Java.net.ConnectException: Connection refused: connect
est générée.
J'ai volontairement choisi un port aussi inhabituel pour voir si c'était le problème, sans succès. Je peux me connecter sans problème en utilisant telnet, mais lorsque j'essaie d'accéder au port avec canyouseeme.org, il me dit que la connexion a expiré. J'ai même essayé de désactiver tous les pare-feu et antivirus, y compris ceux par défaut de Windows et le pare-feu du routeur, avec tous les ports redirigés et DMZ activé, et indique toujours que la connexion est synchronisée. en dehors. J'utilise Comcast comme fournisseur de services Internet et je doute qu'ils bloquent un tel port aléatoire.
Lorsque j'utilise un traceur de paquets, il affiche TCP trafic avec mon ordinateur envoyant SYN et recevant RST/ACK, de sorte qu'il ressemble à un port bloqué standard et qu'aucun autre trafic de paquets suspect n'était en cours.
Je n'ai aucune idée de ce qui se passe à ce stade; J'ai pratiquement essayé tous les tours que je connais. Si quelqu'un savait pourquoi le port pourrait être bloqué ou au moins un moyen de faire fonctionner le programme, ce serait très utile.
Pour ce que ça vaut, votre code fonctionne bien sur mon système.
Je n'aime pas le dire, mais cela ressemble à un problème de pare-feu (que je sais que vous avez déjà vérifié trois fois) ou à un problème de Comcast , qui est plus possible que vous ne le pensez. Je teste ton FAI } _.
Ces problèmes relèvent des situations suivantes:
Client et serveur, l'un ou l'autre ou les deux ne sont pas en réseau.
Le serveur n'est pas en cours d'exécution.
Le serveur est en cours d'exécution mais n'écoute pas sur le port, le client tente de se connecter.
Le pare-feu n'est pas autorisé pour la combinaison hôte/port.
La combinaison de port hôte est incorrecte.
Protocole incorrect dans la chaîne de connexion.
Comment résoudre le problème:
D'abord, vous ping le serveur de destination. Si le ping est effectué correctement, , Alors le client et le serveur sont tous deux sur le réseau.
Essayez de vous connecter à l'hôte et au port du serveur à l'aide de telnet. Si vous êtes en mesure de vous connecter, vous faites des erreurs dans le code client.
Il est probable que le socket du serveur soit uniquement lié à l'adresse localhost. Vous pouvez le lier à une adresse IP spécifique en utilisant la forme à 3 arguments du constructeur.
Je suppose que vous utilisez un routeur pour vous connecter à Internet. Vous devez effectuer une redirection de port pour permettre au public d'accéder à votre réseau interne. Regardez Comment obtenez-vous des sockets Java fonctionnant avec des IP publiques?
J'ai également écrit un article de blog sur le transfert de port, vous voudrez peut-être jeter un oeil :) http://happycoders.wordpress.com/2010/10/03/how-to-setup-a-web-server-by -toi même/
Mais je ne pouvais toujours pas obtenir cet accès sur IP publique, travailler dessus maintenant ...
J'ai eu le même problème parce que parfois le client démarrait avant le serveur et, lorsqu'il tentait de configurer la connexion, il ne parvenait pas à trouver un serveur en fonctionnement.
Ma première solution (pas si élégante) a été d'arrêter le client pendant un moment en utilisant la méthode de veille:
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
J'utilise ce code juste avant la connexion du client, dans votre exemple, juste avant Socket sock = new Socket(HOSTNAME, PORT_NUMBER);
Ma deuxième solution était basée sur ceci réponse. En gros, j'ai créé une méthode dans la classe client. Cette méthode essaie de se connecter au serveur et, si la connexion échoue, elle attend deux secondes avant de réessayer. Voici ma méthode:
private Socket createClientSocket(String clientName, int port){
boolean scanning = true;
Socket socket = null;
int numberOfTry = 0;
while (scanning && numberOfTry < 10){
numberOfTry++;
try {
socket = new Socket(clientName, port);
scanning = false;
} catch (IOException e) {
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
return socket;
}
Comme vous pouvez le constater, cette méthode essaie de créer un socket 10 fois, puis renvoie une valeur nulle pour socket. Soyez donc prudent et vérifiez le résultat.
Votre code devrait devenir:
Socket sock = createClientSocket(HOSTNAME, PORT_NUMBER);
if(null == sock){ //log error... }
Cette solution m'a aidé, j'espère que cela vous aidera aussi. ;-)