2013-05-13 2 views
0

나는 UDP 소켓을 사용하여 자바로 매우 간단한 채팅 응용 프로그램을 만들려고합니다. 하나의 서버와 여러 클라이언트가 있습니다.자바에서 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

+1

Netty 라이브러리 (http://netty.io/) – hoaz

+0

@FDinoff 스레드에 대한 경험이 없습니다. 클라이언트에 MessageListener 클래스가 있고 메시지를 받기 위해이 클래스를 사용하려고했습니다. 현재 다른 사용자가 메시지를 다른 사용자에게 보내지 않는다는 것을 제외하면 내 채팅에서 모든 것이 올바르게 작동합니다. – Adrian

답변

1

만든 스레드가 데이터 그램을 수신하고 변수 in을 채울 때까지 기다리지 않고받은 데이터 그램을 즉시 사용하려고합니다. 수신 된 데이터 그램을 스레드의 코드에서 직접 처리하거나 wait()/notify() 체계를 사용하여 데이터 그램을받을 때 주 스레드에 신호를 보낼 수 있습니다.

+0

'Thread'를 직접 확장하는 것도 가능합니다. –

+0

이제 스레드 코드에서받은 메시지를 처리하고 있지만 다른 명령과 함께 작동하는 것처럼 보이지만/msg는 여전히 작동하지 않습니다. 원래 게시물의 클라이언트 코드를 편집했습니다. – Adrian