2016-11-18 136 views
0

我正試圖在java中使用UDP網絡來設計一個聊天應用程序。UDP中的一個服務器和多客戶端聊天框

這裏是我的服務器:

package ChatBox; 

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
import java.net.SocketException; 
import java.util.Hashtable; 
import java.util.StringTokenizer; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class Server implements Runnable { 

public Hashtable<String, InetAddress> table; 
public Hashtable<String, Integer> tab; 
DatagramSocket sock = new DatagramSocket(5050); 
DatagramPacket pack; 
private String str[]; 
int Port; 

Server(String str[]) throws SocketException, UnsupportedEncodingException, IOException { 
    this.str = str; 
    String Sname = str[2]; 
    System.out.println(Sname); 
    byte[] data = new byte[1000]; 
    pack = new DatagramPacket(data, data.length); 
    sock.receive(pack); 
    String s = new String(data, "UTF-8"); 
    String s1 = s.replaceAll("\n", " "); 
    StringTokenizer st = new StringTokenizer(s1, " "); 
    int f1 = 0, f2 = 0, f3 = 0; 
    String sender; 

    while (st.hasMoreTokens()) { 
     String s2 = st.nextToken(); 
     if (s2.equals("Via:")) { 
      if (st.nextToken().equals(Sname)) { 
       f1 = 1; 
      } 
     } else if (s2.equals("To:")) { 
      if (st.nextToken().equals(Sname)) { 
       f2 = 1; 
      } 
     } 
     else if(s2.equals("From:")) 
     { 
      sender = st.nextToken(); 
      table.put(sender, pack.getAddress()); 
     } 
     else if (s2.equals("Port:")) { 
      Port = Integer.parseInt(st.nextToken()); 
      if (tab.get(Port) != null) { 
       f3 = 1; 
      } 
     } 
    } 
    if ((f1 == 1) && (f2 == 1) && (f3 == 1)) { 
     new Thread(this).start(); 
    } else { 
     if (f1 == 0) { 
      System.out.println("Warning: Server name mismatch. Message dropped."); 
     } 
     if (f2 == 0) { 
      System.out.println("Warning: Server name mismatch. Message dropped."); 
     } 
     if (f3 == 0) { 
      System.out.println("Warning: Unknown recipient. Message dropped."); 
     } 
    } 
} 

public void run() { 
    while (true) { 
     try { 
      String s; 
      String namefind; 
      String name = null; 
      byte[] data = new byte[1000]; 
      DatagramPacket receivePack = new DatagramPacket(data, data.length); 
      sock.receive(receivePack); 
      System.out.println(new String(receivePack.getData())); 
      s = new String(data, "UTF-8"); 
      String s1 = s.replaceAll("\n", " "); 
      StringTokenizer st = new StringTokenizer(s1, " "); 
      while (st.hasMoreTokens()) { 
       namefind=st.nextToken(); 
       if (namefind.equals("Body:")) { 
        namefind = st.nextToken(); 
        StringTokenizer namefind2 = new StringTokenizer(namefind, "$"); 
        name = namefind2.nextToken(); 
        tab.put(name, Port); 
       } 
      } 
      sendPackToClient(receivePack,name); 

     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 
} 
public void sendPackToClient(DatagramPacket receivePack,String name) throws IOException { 
    byte[] data = receivePack.getData(); 
    String s = new String(data, "UTF-8"); 
    InetAddress add = table.get(name); 
    DatagramPacket dp = new DatagramPacket(s.getBytes("UTF-8"), s.getBytes("UTF-8").length, add, Port); 
    sock.send(dp); 
} 

public static void main(String[] args) throws SocketException, IOException { 
    try { 
     String str[]={"java", "Server ","NetworkingAssignmentServer"}; 
     new Server(str); 
    } catch (UnsupportedEncodingException ex) { 
     Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 
} 

這裏是我的客戶:

package ChatBox; 

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
import java.net.SocketException; 
import java.net.UnknownHostException; 
import java.util.Scanner; 
import java.util.StringTokenizer; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class Client { 

Thread send; 
Thread accept; 
DatagramPacket pack; 
DatagramSocket sock; 
private String str[]; 
String name, sname; 
int listeningPort; 
InetAddress server_ip; 
String message, sender; 

public Client(String s[]) throws UnsupportedEncodingException, IOException { 
    this.str = s; 
    name = str[2]; 
    System.out.println(name); 
    listeningPort = Integer.parseInt(str[3]); 
    server_ip = InetAddress.getByName("127.0.0.1"); 
    sname = str[5]; 
    System.out.println(sname); 
    sock = new DatagramSocket(5050); 
    byte[] data = new byte[1000]; 
    pack = new DatagramPacket(data, data.length); 
    sock.receive(pack); 
    String incoming = new String(data, "UTF-8"); 
    String s1 = incoming.replaceAll("\n", " "); 
    StringTokenizer st = new StringTokenizer(s1, " "); 
    int f1 = 0, f2 = 0; 

    while (st.hasMoreTokens()) { 
     String s2 = st.nextToken(); 
     if (s2.equals("Via:")) { 
      if (st.nextToken().equals(sname)) { 
       f1 = 1; 
      } 
     } else if (s2.equals("To:")) { 
      if (st.nextToken().equals(name)) { 
       f2 = 1; 
      } 
     } 

    } 
    if ((f1 == 1) && (f2 == 1)) { 
     send = new Thread() { 

      public void run() { 
       while (true) { 
        try { 
         InetAddress host = InetAddress.getByName("localhost"); 
         try { 
          Scanner input = new Scanner(System.in); 
          String in = input.nextLine(); 
          System.out.println(in); 
          StringBuffer str = new StringBuffer(""); 
          str.append("Via: "); 
          str.append(sname + "\n"); 
          str.append("To: " + sname + "\n"); 
          str.append("From: " + name + "\n"); 
          str.append("Body: " + in); 
          byte[] data = new byte[1000]; 
          data = str.toString().getBytes("UTF-8"); 
          DatagramPacket sendPack = new DatagramPacket(data, data.length, host, 5050); 
          sock.send(sendPack); 
         } catch (Exception e) { 
          System.out.println(e); 
         } 
        } catch (UnknownHostException ex) { 
         Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex); 
        } 
       } 
      } 

     }; 
     send.start(); 
     accept = new Thread() { 

      public void run() { 
       while (true) { 
        try { 
         sock = new DatagramSocket(5050); 
         byte[] data = new byte[1000]; 
         pack = new DatagramPacket(data, data.length); 
         sock.receive(pack); 
         String incoming = new String(data, "UTF-8"); 
         String s1 = incoming.replaceAll("\n", " "); 
         StringTokenizer st = new StringTokenizer(s1, " "); 
         while (st.hasMoreTokens()) { 
          String s2 = st.nextToken(); 
          if (s2.equals("From:")) { 
           s2 = st.nextToken(); 
           StringTokenizer namefind = new StringTokenizer(s2, "$"); 
           sender = namefind.nextToken(); 
          } else if (s2.equals("Body:")) { 
           s2 = st.nextToken(); 
           while (st.hasMoreTokens()) { 
            message = st.nextToken(); 
           } 
          } 
         } 
         System.out.println(sender + " says: " + message); 
        } catch (UnknownHostException ex) { 
         Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex); 
        } catch (SocketException ex) { 
         Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex); 
        } catch (IOException ex) { 
         Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex); 
        } 
       } 
      } 
     }; 
     accept.start(); 
    } 
} 

public static void main(String[] args) throws IOException { 
    String str[] = {"Java", "Client", "Sheba", "12345", " 127.0.0.1", "NetworkingAssignmentServer"}; 
    new Client(str); 
} 

} 

但我總是收到錯誤,如:

Exception in thread "main" java.net.BindException: Address already in use: Cannot bind 
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method) 
at java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:84) 
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:93) 
at java.net.DatagramSocket.bind(DatagramSocket.java:392) 
at java.net.DatagramSocket.<init>(DatagramSocket.java:242) 
at java.net.DatagramSocket.<init>(DatagramSocket.java:299) 
at java.net.DatagramSocket.<init>(DatagramSocket.java:271) 
at ChatBox.Client.<init>(Client.java:44) 
at ChatBox.Client.main(Client.java:140) 
C:\Users\HP\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53:   Java returned: 1 
BUILD FAILED (total time: 0 seconds) 

我應該做的?任何幫助將非常感激。

+0

你至少應該嘗試在引發異常的代碼部分隔離開來。這是一個[最小示例](http://stackoverflow.com/help/mcve)? –

+0

我認爲你的服務器和客戶端使用相同的端口和地址,你是否在同一臺PC上使用服務器和客戶端? – user2760751

+0

@ user2760751是的。可以。請告訴我應該在哪裏做出改變? – IAmBlake

回答

0

我注意到服務器代碼和客戶端代碼都使用相同的端口5050,當他們在同一臺PC時,綁定會返回錯誤。

所以你應該把不同的端口放到服務器和客戶端。或者您可以使用不同的PC分別運行服務器和客戶端。

在此聲明將不同:

sock = new DatagramSocket(5050); // Server : 5050, Client 5000