2011-05-31 109 views
1

我寫了兩個程序。現在每個程序都使用線程來同時發送和接收數據包。 每當我將數據包從服務器發送到客戶端時,客戶端的消息都會以無限循環接收。即;我已經添加了一條打印語句,用於打印發送的消息,並且在無限循環中永遠消失。我想讓它接收消息,然後能夠回寫到服務器並在用戶需要時退出。Java中的UDP線程無限循環

我試過使用socket.close(),但這使得客戶端收到消息,我只能寫回服務器一次。我發送後,我不能再發送了。我想讓它可以多次寫回。

任何人都可以請指出我在正確的方向嗎?

我的代碼如下;

public class UDPThreadClient extends Thread { 

public static int port1; 

//Create threaded server 
UDPThreadClient (int port1) { 
    System.out.println ("Starting threaded client"); 
    start(); 
} 

public void run() { 

    int port = port1; 

    try { 
     DatagramSocket serverSocket = new DatagramSocket(port1); 
      byte[] receiveData = new byte[1024]; 
      byte[] sendData = new byte[1024]; 

      while (true) { 
       DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); 
       serverSocket.receive(receivePacket); 
       String sentence = new String(receivePacket.getData()); 
       SocketAddress address = receivePacket.getSocketAddress(); 


       System.out.println("RECEIVED from " + address + " : " + sentence); 

       InetAddress IPAddress = receivePacket.getAddress(); 
       //int port = receivePacket.getPort(); 
       String capitalizedSentence = sentence.toUpperCase(); 
       sendData = capitalizedSentence.getBytes(); 
       DatagramPacket sendPacket = 
       new DatagramPacket(sendData, sendData.length, IPAddress, port); 
       serverSocket.send(sendPacket); 
       //serverSocket.close(); 
      } 
    } catch (IOException e) { 
     System.out.println (e.getMessage()); 
    } 

} 

//Create client 
public static void main(String[] args) { 

    int port = Integer.parseInt(args[0]); 
    port1 = Integer.parseInt(args[1]); 
    new UDPThreadClient (port1); 
    try { 

      BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); 

      DatagramSocket clientSocket = new DatagramSocket(); 
      InetAddress IPAddress = InetAddress.getByName("localhost"); 

      byte[] sendData = new byte[1024]; 
      byte[] receiveData = new byte[1024]; 

      String sentence = inFromUser.readLine(); 

      sendData = sentence.getBytes(); 

      DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); 

      clientSocket.send(sendPacket); 

      DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); 

      clientSocket.receive(receivePacket); 

      String modifiedSentence = new String(receivePacket.getData()); 

      System.out.println("FROM SERVER:" + modifiedSentence); 

     //clientSocket.close(); 
    } catch (IOException e) { 
     System.out.println (e.getMessage()); 
    } 
} 
    } 

public class UDPThreadServer extends Thread { 

public static int port1; 

//Create threaded client 
UDPThreadServer() { 

    System.out.println ("Starting threaded server"); 
    start(); 


} 

public void run() { 

    try { 
     DatagramSocket clientSocket = new DatagramSocket(); 

      BufferedReader inFromUser = new BufferedReader (new InputStreamReader(System.in)); 
      Scanner in = new Scanner (inFromUser); 
      InetAddress IPAddress = InetAddress.getByName("localhost"); 
     byte[] sendData = new byte [1024]; 
     byte[] receiveData = new byte [1024]; 

     while (in.hasNextLine()) { 
     String sentence = in.nextLine(); 
     //inFromUser.readLine(); 
     sendData = sentence.getBytes(); 

     DatagramPacket sendPacket = new DatagramPacket (sendData, sendData.length, IPAddress, port1); 
     clientSocket.send(sendPacket); 

     DatagramPacket receivePacket = new DatagramPacket (receiveData, receiveData.length); 
     clientSocket.receive (receivePacket); 

     String modSentence = new String (receivePacket.getData()); 
     System.out.println ("FROM SERVER: " + modSentence); 
     } 
     //clientSocket.close(); 
    } catch (IOException e) { 
     System.out.println (e.getMessage()); 
    } 

} 

//Create server 
public static void main(String[] args) { 

    int port = Integer.parseInt(args[0]); 
    port1 = Integer.parseInt(args[1]); 
    new UDPThreadServer(); 
    try { 
     DatagramSocket serverSocket = new DatagramSocket (port); 
     byte[] receiveData = new byte[1024]; 
     byte[] sendData = new byte[1024]; 

     while (true) { 
      DatagramPacket receivePacket = new DatagramPacket (receiveData, receiveData.length); 
      serverSocket.receive(receivePacket); 
      String sentence = new String(receivePacket.getData()); 
      SocketAddress address = receivePacket.getSocketAddress(); 
      System.out.println ("Received from " + address + " : " + sentence); 

      InetAddress IPAddress = receivePacket.getAddress(); 
      String capSentence = sentence.toUpperCase(); 
      sendData = capSentence.getBytes(); 
      DatagramPacket sendPacket = new DatagramPacket (sendData, sendData.length, IPAddress, port); 
      serverSocket.send(sendPacket); 
      //serverSocket.close(); 
     } 

    } catch (IOException e) { 
     System.out.println (e.getMessage()); 
    } 
} 

} 

感謝。

回答

1

看着UDPClientServer:

當您創建的數據報文包,你給它的端口發送它,而不是你從它發送的端口。

當我運行你的代碼時,什麼都沒有發生。服務器正在等待端口port,而客戶端則發送到端口port1。如果您發送到端口port(不能從主方法訪問,但將其更改爲字段而不是本地方法會解決該問題,則會發生無限循環,因爲服務器會將數據包發送到正在偵聽的同一端口。 。你的問題你提供同樣的數字作爲第一和第二參數程序

從服務器,你可以使用receivePacket.getPort()獲得其中分組來自的端口

編輯:?

你的兩個班有很多重複,這可能是一個混亂的來源。主要啓動客戶端,然後創建一個服務器類型的循環測試器。另一個類設置一個Server,然後創建一個客戶端類型測試器。

下面只是您命名爲UDPThreadServer的類,其中註釋顯示了使主服務器與主方法中的測試代碼「工作」的更改。請注意,服務器應該發送到它不在監聽的端口。您還正在從命令行參數中讀取端口值。我只是爲這些端口編了一些數字,並將它們作爲常量加以固定。

public class UDPThreadServer extends Thread 
{ 

    public static int port1; 

    UDPThreadServer() 
    { 
    //server or client? it's hard to say. you call the socket a clientSocket. 
    System.out.println("Starting threaded server"); 
    start(); 
    } 

    public void run() 
    { 
    try 
    { 
     // Here client(?) is set up with empty constructor. 
     // It is a mystery what port it will get. 
     DatagramSocket clientSocket = new DatagramSocket(); 

     BufferedReader inFromUser = 
      new BufferedReader(new InputStreamReader(System.in)); 
     Scanner in = new Scanner(inFromUser); 
     InetAddress IPAddress = InetAddress.getByName("localhost"); 
     byte[] sendData = new byte[1024]; 
     byte[] receiveData = new byte[1024]; 

     while (in.hasNextLine()) 
     { 
     String sentence = in.nextLine(); 
     // inFromUser.readLine(); 
     sendData = sentence.getBytes(); 

     // sending to port1? that must be the server. 
     DatagramPacket sendPacket = 
      new DatagramPacket(sendData, sendData.length, IPAddress, port1); 
     clientSocket.send(sendPacket); 

     DatagramPacket receivePacket = 
      new DatagramPacket(receiveData, receiveData.length); 
     clientSocket.receive(receivePacket); 

     String modSentence = new String(receivePacket.getData()); 
     System.out.println("FROM SERVER: " + modSentence); 
     } 
     // clientSocket.close(); 
    } catch (IOException e) 
    { 
     System.out.println(e.getMessage()); 
    } 
    } 

    // Create server 
    public static void main(String[] args) 
    { 

    // int port = Integer.parseInt(args[0]); 
    int port = 1927; // or whatever 
    // port1 = Integer.parseInt(args[1]); 
    port1 = 1928; 
    new UDPThreadServer(); 
    try 
    { 
     // server resides on port1? if client sends to port 1, then this is so. 
     DatagramSocket serverSocket = new DatagramSocket(port1); 
     byte[] receiveData = new byte[1024]; 
     byte[] sendData = new byte[1024]; 

     while (true) 
     { 
     DatagramPacket receivePacket = 
      new DatagramPacket(receiveData, receiveData.length); 
     serverSocket.receive(receivePacket); 
     String sentence = new String(receivePacket.getData()); 
     SocketAddress address = receivePacket.getSocketAddress(); 
     System.out.println("Received from " + address + " : " + sentence); 

     InetAddress IPAddress = receivePacket.getAddress(); 
     String capSentence = sentence.toUpperCase(); 
     sendData = capSentence.getBytes(); 

     // where did you get the info from? Client is set up with an empty constructor, so it is a mystery. 
     port = receivePacket.getPort(); 

     DatagramPacket sendPacket = 
      new DatagramPacket(sendData, sendData.length, IPAddress, port); 
     serverSocket.send(sendPacket); 
     // serverSocket.close(); 
     } 

    } catch (IOException e) 
    { 
     System.out.println(e.getMessage()); 
    } 
    } 
} 
+0

感謝Atreys,當我嘗試打印getPort()的值時,我得到-1。當我真的刪除while(true)時,while循環停止。但是,我仍然無法發送多次。我明白你的意思,而我現在只是有點困惑,因爲沒有while循環,一切似乎都能正常工作,只是我無法發送一次以上的事實。 – Triple777er 2011-05-31 11:36:50

+0

@ Triple777er,我編輯了我的答案,並對UDPThreadServer進行了修改,使其與主要方法一起工作。 – Atreys 2011-05-31 14:28:39

+0

非常感謝Atreys,這幫助我解決了我的問題。感謝您花時間幫助我。非常感激。 – Triple777er 2011-06-01 05:27:28

0

請勿關閉插座。

如果這不能回答你的問題,你需要澄清它。

+0

我還沒有關閉socket。每當我從服務器發送消息時,例如; 「hello」,在接收端,它在無限循環中打印hello。 – Triple777er 2011-05-31 10:12:08

+0

@ Triple777er我懷疑你是將回復發回給自己,而不是寄給發件人。答覆地址已經在收到的DatagramPacket中:只需將答覆數據放在那裏併發送。 – EJP 2011-05-31 12:34:00

0

while(true)是一個無限循環。無論如何你會放棄它嗎?

+0

Setala,是的,我嘗試刪除while(true)並停止無限循環。但是,我無法將任何數據寫回服務器。我只能寫一次。 – Triple777er 2011-05-31 10:41:20