2013-05-13 68 views
0

我正尝试使用UDP套接字在Java中创建一个非常简单的聊天应用程序。有一台服务器和多个客户端。java中的UDP套接字聊天应用程序

现在我的代码是:

服务器:

package chat; 

import java.io.*; 
import java.net.*; 
import java.util.HashMap; 
import java.util.Set; 

class User{ 
    InetAddress addr; 
    int port; 

    User(InetAddress a,int p){ 
     addr = a; 
     port = p; 
    } 
} 



public class Server { 
    private static final int PORT = 27012; 
    private static DatagramSocket sckt; 
    private static DatagramPacket in,out; 
    private static byte[] buffer; 
    private static HashMap<String,User> users; 
    public static void main(String[] args) { 
     try{ 
      System.out.println("Opening port..."); 
      sckt = new DatagramSocket(PORT); 
      users = new HashMap<String,User>(); 

     } 
     catch(SocketException e){ 
      System.out.println("Port connection failed!"); 
      System.exit(1); 
     } 

     handleClient(); 
    } 
     private static void sendMsg(InetAddress addr, int port, String msg){ 
      try{ 
      out = new DatagramPacket(msg.getBytes(),msg.length(),addr,port); 
      sckt.send(out); 
      }catch(IOException e){ 
       e.printStackTrace(); 
      } 
     } 
    private static void handleClient(){ 
     try{ 
      String msgIn,msgOut="",senderNick; 
      do{ 
      buffer = new byte[256]; 
      in = new DatagramPacket(buffer,buffer.length); 
      sckt.receive(in); 
      InetAddress clientAddress = in.getAddress(); 
      int clientPort = in.getPort(); 
      msgIn = new String(in.getData(),0,in.getLength()); 
      //print msgIn 
      //System.out.println(msgIn); 
         senderNick = msgIn.substring(0,msgIn.indexOf(" ")); 
         msgIn = msgIn.substring(msgIn.indexOf(" ")+1); 
      if(msgIn.equals("/connect")){ 
       //String nick = msgIn.substring(msgIn.indexOf(" ") + 1); 
       System.out.println(senderNick); 
       if(users.containsKey(senderNick)){ 
        msgOut = "Nick already in use!"; 
       } 
       else{ 
        users.put(senderNick, new User(clientAddress,clientPort)); 
        msgOut = "Connected!"; 
       } 
           sendMsg(clientAddress,clientPort,msgOut); 
      } 
         else if(msgIn.equals("/list")){ 
          Set userNames; 
          userNames = users.keySet(); 
          msgOut = "Users : \n"; 
          msgOut += userNames.toString(); 
          sendMsg(clientAddress,clientPort,msgOut); 
         } 
         else if(msgIn.startsWith("/msg")){ 
          String tmp = msgIn.substring(msgIn.indexOf(" ")+1); 
          String receiverName = tmp.substring(0,tmp.indexOf(" ")); 
          String message = tmp.substring(tmp.indexOf(" ")+1); 

          if(!users.containsKey(receiverName)){ 
           msgOut = "User " + receiverName + " not found!"; 
           sendMsg(clientAddress,clientPort,msgOut); 
          } 
          else{ 
           User receiver = users.get(receiverName); 
           msgOut = "Message from "+ senderNick +" : "+message; 
           sendMsg(clientAddress,clientPort,"Message Sent!"); 
           sendMsg(receiver.addr,receiver.port,msgOut); 
          } 

         } 
         else if(msgIn.startsWith("/nick")){ 
          String newNick = msgIn.substring(msgIn.indexOf(" ")+1); 
          if(users.containsKey(newNick)){ 
           msgOut = "Nick already in use!"; 
          } 
          else{ 
           users.put(newNick,users.get(senderNick)); 
           users.remove(senderNick); 
           msgOut = "Nick changed!"; 
          } 
          sendMsg(clientAddress,clientPort,msgOut); 
         } 
         else if(msgIn.equals("/disconnect")){ 
          users.remove(senderNick); 
         } 

      //out = new DatagramPacket(msgOut.getBytes(),msgOut.length(),clientAddress,clientPort); 
      //sckt.send(out); 
      }while(true); 
     } 
     catch(IOException e){ 
      e.printStackTrace(); 
     } 
     finally{ 
      System.out.println("Closing connection."); 
      sckt.close(); 
     } 
    } 

} 

客户:

package chat; 

import java.io.*; 
import java.net.*; 
import java.util.Scanner; 

public class Client { 

    private static InetAddress host; 
    private static final int PORT = 27012; 
    private static DatagramSocket sckt; 
    private static DatagramPacket in, out; 
    private static byte[] buffer; 
    private static String nick; 

    static class MessageListener implements Runnable { 
     //DatagramPacket in; 
     //byte[] buffer; 
     String reply; 
     public void run() { 
      do{ 
      try{ 
      buffer = new byte[256]; 
      in = new DatagramPacket(buffer,buffer.length); 
      sckt.receive(in); 
      reply = new String(in.getData(),0,in.getLength()); 
      System.out.println("SERVER> "+reply); 
      } 
      catch(IOException e){ 
       e.printStackTrace(); 
      } 
      }while(true); 
     } 
    } 

    public static void main(String[] args) { 
     try { 
      host = InetAddress.getLocalHost(); 

     } catch (UnknownHostException e) { 
      System.out.println("Host not found!"); 
      System.exit(1); 
     } 
     connect(); 

    } 

    private static void sendMsg(String msg) { 
     try { 
      out = new DatagramPacket(msg.getBytes(), msg.length(), host, PORT); 
      sckt.send(out); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private static void connect() { 
     Scanner sc = new Scanner(System.in); 

     try { 
      buffer = new byte[256]; 
      sckt = new DatagramSocket(); 
      String reply = ""; 
      do { 
       System.out.println("Name: "); 
       nick = sc.nextLine(); 
       sendMsg(nick + " /connect"); 
       in = new DatagramPacket(buffer, buffer.length); 
       sckt.receive(in); 
       reply = new String(in.getData(), 0, in.getLength()); 
       System.out.println("SERVER> " + reply); 
      } while (!reply.equals("Connected!")); 
      accessServer(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private static void accessServer() { 
     try { 
      sckt = new DatagramSocket(); 
      Scanner sc = new Scanner(System.in); 
      String msg = "", reply = ""; 
      Thread myT = new Thread(new MessageListener()); 
      myT.start(); 
      do { 
       System.out.print("Enter Message: "); 
       msg = sc.nextLine(); 
       if (!msg.equals("/quit")) { 
        buffer = new byte[256]; 

        sendMsg(nick + " " + msg); 


       } else { 
        sendMsg(nick + " /disconnect"); 
       } 
      } while (!msg.equals("/quit")); 

      sc.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      System.out.println("Connection closing..."); 
      sckt.close(); 
     } 

    } 
} 

我希望能够将消息发送给单个用户或所有用户但问题是我无法在客户端上收到消息,因为现在客户端只会在将消息发送到服务器后收到消息。所以我的想法是使用一个线程连续监听来自服务器的消息,但它不起作用。最简单的方法是什么?

+0

为什么你的意思是由线程不起作用? – FDinoff 2013-05-13 21:05:01

+1

看看Netty库(http://netty.io/) – hoaz 2013-05-13 21:05:39

+0

@FDinoff我对线程没有任何经验。我在客户端有一个MessageListener类,我试图用它来接收消息:现在,在我的聊天中一切正常,除了当我向另一个用户发送消息时,另一个用户没有得到它。 – Adrian 2013-05-13 21:09:03

回答

1

您试图立即使用收到的数据报,而不是等待您创建的线程接收数据报并填充您的in变量。您可以直接在线程代码中处理收到的数据报,或者在使用wait()/ notify()方案接收到数据报时通知主线程。

+0

也可以直接扩展'Thread'。 – 2013-05-13 21:39:32

+0

我现在正在处理线程代码中收到的消息,它似乎与其他命令一起工作,但是/ msg仍然不起作用。在原始帖子中编辑客户端代码。 – Adrian 2013-05-13 21:48:17