2015-08-09 2 views
0

im делает чат-программу P2P. для этого я использую дейтаграммы UDP. но у меня есть некоторые проблемы.Java UDP p2p chatprogram.

иногда программа работает без проблем. но в большинстве случаев только 1 из 2 человек получают сообщение, или иногда ни один из двух человек не получает сообщение. im думает о том, чтобы пойти в 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 является ненадежным, вы не можете быть уверены в том, что сообщение поступило, но в программе чата это не желаемое поведение ... Чтобы решить эту проблему, вам придется реализовать механизмы, подобные TCP, поверх UDP, чтобы вы могли быть уверены пришло сообщение (если оно не будет повторно отправлено). Но тогда вы изобретаете колесо. Я бы просто использовал TCP, это не сильно изменит код, и вы уверены, что ** все ** сообщения приходят. – HyperZ

+1

P2P не является взаимоисключающим с TCP, каждый клиент также может выступать в качестве сервера. Вы можете имитировать бесконтактную связь (и держать вещи простыми - границы сообщений), только отправляя/получая по одному сообщению на соединение. – XA21X

+0

Я изучал это, но все они, похоже, работают с центральным сервером. не могли бы вы помочь мне с тем, что я должен изменить, чтобы сделать это tcp? –

ответ

1

, если любой из вас выявить проблему или помочь мне, что было бы здорово

«Проблема» не всех сообщений, добирающихся до места назначения, является нормальным, потому что UDP ненадежен. Это связано не с вашим кодом (из-за того, что вы используете UDP вместо TCP).

Если вы хотите быть уверенным, что каждое сообщение прибывает в пункт назначения, у вас есть 2 возможности. Вы можете использовать TCP вместо UDP, поскольку TCP гарантирует, что каждое сообщение придет (и гарантирует еще больше). Если вы действительно хотите продолжить работу с UDP, вам придётся отправить подтверждение (первому отправителю сообщения) при получении сообщения. Когда отправитель получает подтверждение, он может быть уверен, что сообщение прибыло в пункт назначения. Однако есть много дополнительных проблем, которые вы должны исправить, если используете UDP (порядок сообщений, ...). Поэтому я бы просто рекомендовал использовать TCP вместо того, чтобы изобретать колесо.

Я думаю о переходе на TCP, но я хочу сохранить его P2P, поэтому нет центрального сервера.

Этого будет трудно достичь. Существуют различные возможности для реализации Peer-равному система:

  • С центральной coordinater
  • По наводнения
  • По распределенных хэш-таблиц

Первый подход является самым простым, но невозможно, поскольку вы явно не хотите центрального сервера. Но другие подходы значительно сложнее.