2015-08-09 185 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
  • 被洪水
  • 通过分布式哈希表

第一种方法是最简单的,但不可能,因为你明确地不需要中央服务器。但其他方法则相当困难。