2017-07-27 2 views
0

J'écris un programme pour envoyer un entier (variable appelée intToSend) sur un réseau utilisant UDP. Je cours le programme sur deux machines sur le même réseau, l'un après l'autre. Je pensais qu'après les avoir exécutées toutes les deux, la première à lancer ouvrirait une boîte de message avec l'entier envoyé, mais cela n'arrivera pas. Les deux programmes attendent qu'un paquet soit reçu comme indiqué par "Waiting ..." en cours d'impression sur la console. J'ai le programme demande à l'ip de destination d'être entré dans la console. Puis, après cela, la méthode createSocket est appelée, suivie de sendData, puis receiveData.Envoi de paquets de datagrammes en Java

Voici le code:

package main; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintStream; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
import java.net.InetSocketAddress; 
import java.net.SocketException; 
import java.net.URL; 
import java.net.UnknownHostException; 
import java.util.Scanner; 

import javax.swing.JOptionPane; 

public class Main { 

    Scanner s = new Scanner(System.in); 
    PrintStream o = System.out, e = System.err; 

    InetAddress thisAddr, destAddr; 
    DatagramSocket socket; 

    int port = 1729, intToSend = 8; 

    boolean running = true; 

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

    private Main() { 
     try { 
      thisAddr = InetAddress.getLocalHost(); 
      System.out.println("Internal IP: " + thisAddr.getHostAddress().toString()); 
      System.out.println("External IP: " + getIp()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     try { 
      destAddr = InetAddress.getByName(getDestIp()); 
     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } 

     createSocket(); 
     sendData(); 
     receiveData(); 
    } 

    private void receiveData(){ 
     byte[] receiveBuffer = new byte[1024]; 
     DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length); 
     while(true){ 
      System.out.println("Waiting..."); 
      try { 
       socket.receive(receivePacket); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      String receivedText = new String(receivePacket.getData()); 
      JOptionPane.showMessageDialog(null, receivedText); 
     } 
    } 

    private void sendData(){ 
     byte[] dataToSend = String.valueOf(intToSend).getBytes(); 
     DatagramPacket packet = new DatagramPacket(dataToSend, dataToSend.length, destAddr, port); 
     try { 
      socket.send(packet); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void createSocket(){ 
     try { 
      socket = new DatagramSocket(port); 
     } catch (SocketException e) { 
      e.printStackTrace(); 
     } 
    } 


    public static String getIp() throws IOException{ 
     URL whatismyip = new URL("http://icanhazip.com"); 
     BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream())); 
     return in.readLine(); 
    } 

    private String getDestIp() { 
     String temp; 
     o.println("What is the other user's ip?"); 
     temp = s.nextLine(); 
     return temp; 
    } 
} 
+1

Vous n'avez pas fourni suffisamment d'informations. Je suppose que vous exécutez ceci sur un seul thread, donc receiveData est toujours dans la boucle while (true). –

+0

@ChristopherSchneider C'est le point. Je lance le programme sur l'ordinateur 1 et lui donne l'adresse IP de l'ordinateur 2. Il crée ensuite le socket, envoie les données à l'ordinateur 2 qui n'a pas le programme en cours d'exécution et n'écoute donc pas les paquets. L'ordinateur 1 est alors à l'écoute des paquets. Ensuite, le programme est exécuté sur l'ordinateur 2. Je lui donne l'ip de l'ordinateur 1 et donc il devrait envoyer un paquet à l'ordinateur 1 et il devrait être reçu comme l'ordinateur 1 écoute des paquets. – Matty2532

+0

Ok ... où est ce code? Vous avez montré quelques méthodes, mais pas de code d'initialisation. –

Répondre

0

Ce code fonctionne pour moi. Si je saisis l'adresse IP cible en tant qu'IP de la machine locale, j'obtiens le popup. Si je saisis une autre machine sur le réseau, j'obtiens aussi le popup. Je suppose que l'une de vos machines a un pare-feu qui bloque le paquet UDP entrant, ou que vos machines ont plusieurs interfaces réseau et que l'IP que vous détectez n'est pas celle qui se trouve sur le même réseau que l'autre machine. Dans le premier cas, vous pouvez désactiver le pare-feu (ce n'est pas une bonne idée si vos machines ne sont pas derrière un routeur avec un pare-feu ou sur un réseau dont vous n'avez pas le contrôle total) ou ouvrir le port spécifique UDP entrant et sortant sur les deux machines. Dans ce dernier cas, vous voulez rechercher les adresses IP présentées sur les deux machines se trouvant sur le même sous-réseau (les trois premiers chiffres étant les mêmes dans le cas où IPv4), par exemple, IPv4. les deux commençant par 192.168.1. ou similaire. Lorsque vous recevez votre paquet, vous obtiendrez probablement une fenêtre popup très longue car vous allouez un tableau de 1 024 octets et mettez la chaîne au début de ce tableau, puis convertissez le tableau entier de 1 024 octets en une chaîne qui peut inclure divers trucs à la fin des N premiers octets dans lesquels vous avez écrit l'int.

Il existe différentes façons de résoudre cela, mais cela, mais un moyen simple d'être en mesure d'emballer un tas de données dans un paquet, puis le relire est d'utiliser de manière fiable bytearrayinput/OutputStreams et DataInput/OutputStreams:

//Sending side 
ByteArrayOutputStream bout = new ByteArrayOutputStream(); 
DataOutputStream dout = new DataOutputStream(bout); 
dout.writeInt(N); //this will write 4 bytes 
byte[] packetData = bout.toByteArray(); 

//Receiving side 
byte[] packetBuffer = ...; 
ByteArrayInputStream bin = new ByteArrayInputStream(packetBuffer); 
DataInputStream din = new DataInputStream(bin); 
int N = din.readInt(); //This will read only the first 4 bytes, and use the same marshalling as DataOutputStream to produce a consistent value, even if the integer value is something exceptional like infinity or NaN. 
+0

Merci, cela a fonctionné. J'ai oublié d'ajouter des règles à l'intérieur du pare-feu Windows sur les deux ordinateurs. J'avais aussi une carte réseau virtuelle qui me donnait la mauvaise adresse IP sur l'un de mes ordinateurs. – Matty2532