2015-08-09 182 views
0

即時通訊製作P2P聊天程序。爲此我使用UDP數據報。但即時通訊有一些問題。Java UDP p2p聊天程序。

有時程序運行沒有任何問題。但大多數時候只有兩個人中的一個接收到該消息,或者有時兩個人中的任何一個都沒有收到消息。即時考慮去TCP,但我想保持P2P,所以沒有中央服務器。

我的代碼:

package herexChatProg; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
import java.net.SocketException; 

import javax.swing.JOptionPane; 

import login.MainScreen; 

public class MessageSender extends Thread { 
private int Port; 
private String recIP; 
private final static BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 

private MainScreen Screen; 

private DatagramSocket ds = null; 
private DatagramPacket dp = null; 

public MessageSender(MainScreen m, String ip, int port) throws Exception { 
    recIP = ip; 
    Port = port; 
    Screen = m; 
    System.out.println("chat program: IP address: " + recIP + " port " + Port); 
    start(); 

} 

public void run() { 
    try { 
     // open DatagramSocket to receive 
     ds = new DatagramSocket(Port); 
     // loop forever reading datagrams from the DatagramSocket 
     while (true) { 
      byte[] buffer = new byte[65000]; // max char length 
      dp = new DatagramPacket(buffer, buffer.length); 
      ds.receive(dp); 
      String s = new String(dp.getData(), 0, dp.getLength()); 

      Screen.writeText(s); 
      // System.out.println("UDP datagram length " + s.length() + " 
      // from IP " + dp.getAddress() + " received: " + s); 
     } 
    } catch (SocketException se) { 
     System.err.println("chat error (Socket Closed = good): " + Se.getMessage()); 
     JOptionPane.showMessageDialog(null, "Please check your connection or try to log on again"); 
     } catch (IOException se) { 
     System.err.println("chat error: " + se.getMessage()); 
    } 
} 

public void Stop() { 
    if (ds != null) { 
     ds.close(); 
     ds = null; 
    } 
} 



public boolean sendMessage(String message) throws IOException { 
    try { 
     System.out.println("Sending to " + recIP + " socket " + Port + " data: " + message); 
     byte[] data = message.getBytes(); 
     DatagramSocket theSocket = new DatagramSocket(); 
     DatagramPacket theOutput = new DatagramPacket(data, data.length, InetAddress.getByName(recIP), Port); 
     theSocket.send(theOutput); 
     Screen.writeText(message); 
     return true; 
    } catch (IOException e) { 
     return false; 
    } 
} 

}

如果你們發現問題或能幫助我,將是巨大

感謝DenTilloZie

+1

UDP是不可靠的,你不能確定一個消息到達,但在一個聊天程序,這是不是所需的行爲......爲了解決這個問題,你將不得不在UDP之上實現TCP機制,所以你可以肯定一條消息到達(如果不重新發送)。但是,你正在重新發明輪子。我只會使用TCP,這對代碼沒有什麼太大的影響,並且你確信**全部**消息到達。 – HyperZ

+1

P2P與TCP並不互斥,每個客戶端也可以充當服務器。您可以通過每個連接只發送/接收一條消息來模擬無連接通信(並且保持簡單 - 消息邊界)。 – XA21X

+0

我一直在研究這個,但他們似乎都與中央服務器一起工作。你能幫我改變一下tcp嗎? –

回答

1

如果哪發現問題或可以幫助我,這將是偉大的

並非所有消息到達目的地的「問題」都是正常的,這是因爲UDP不可靠。這不是由於你的代碼(很好,因爲你使用UDP而不是TCP)。

如果你想確保每封郵件到達目的地,你有兩種可能性。你可以使用TCP而不是UDP,因爲TCP保證每條消息到達(並且保證更多)。如果你真的想繼續使用UDP,你將不得不在發送消息時發送一個確認(給消息的原始發送者)。當發件人收到確認時,他可以確定郵件到達目的地。但是,如果您使用UDP(消息順序,...),則還有很多額外的問題需要解決。所以我只是推薦使用TCP而不是重新發明輪子。

即時考慮去TCP,但我想保持它的P2P,所以沒有中央服務器。

這將很難實現。有用於實現對等網絡系統不同的可能性:

  • 隨着中央coordinater
  • 被洪水
  • 通過分佈式哈希表

第一種方法是最簡單的,但不可能,因爲你明確地不需要中央服務器。但其他方法則相當困難。