개인참고자료/자바(네트워크)

UDP 프로그래밍 - 에코 클라이언트 / 서버 프로그래밍

경진 2008. 7. 19. 17:38
UDP를 이용한 에코 클라이언트 / 서버 프로그래밍

에코 서버 프로그래밍

import java.net.*;            
           
public class UDPEchoServer {            
    public static void main(String[] args) {       
        if(args.length != 1){   
            System.out.println("사용법 : java UDPEchoServer port");
            System.exit(1);
        }   
        int port = 0;   
        try{   
            port = Integer.parseInt(args[0]);
        }catch(Exception ex){   
            System.out.println("port 번호는 양의 정수로 입력하여 주세요.");
            System.exit(1);
        }           
        DatagramSocket dsock = null;           
        try{           
            System.out.println("접속 대기상태입니다.");       
            dsock = new DatagramSocket(port);       
            String line = null;       
            while(true){       
                // 받기   
                byte[] buffer = new byte[1024];   
                DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length);   
                dsock.receive(receivePacket);   
                String msg = new String(receivePacket.getData(),0, receivePacket.getLength());   
                System.out.println("전송받은 문자열 : " + msg );   
                if(msg.equals("quit"))   
                    break;
                // 전송   
                DatagramPacket sendPacket = new DatagramPacket(receivePacket.getData(), receivePacket.getData().length, receivePacket.getAddress(), receivePacket.getPort());   
                dsock.send(sendPacket);   
            } // while       
            System.out.println("UPDEchoServer를 종료합니다.");       
        }catch(Exception ex){           
            System.out.println(ex);       
        }finally{           
            if(dsock != null)       
                dsock.close();   
        }           
    } // main               
} // class                   

클라이언트에게 DatagramPacket을 전송하거나 수신하기 위해서 DatagramSocket 객체를 생성했다. 그리고 동작할 포트 값을 DatagramSocket 생성자에 인자로 지정한다.

        DatagramSocket dsock = null;           
        try{           
            System.out.println("접속 대기상태입니다.");       
            dsock = new DatagramSocket(port);

클라이언트로부터 DatagramPacket을 전송 받기 위해서 DatagramPacket 객체 하나를 생성한 후, DatagramSocket의 receive() 메소드에 인자로 지정함으로써 클라이언트가 패킷을 전송할 때까지 대기한다. DatagramPacket을 전달 받을 경우, 바이트 배열과 바이트 배열의 크기를 지정하게 된다.

클라이언트가 패킷을 전송했을 경우에는 receive() 메소드의 다음 행이 실행된다. 전송 받은 데이터가 바이트 배열이기 때문에 String 생성자에 바이트 배열과 크기를 지정해서 String 객체를 생성한 후, 전송 받은 결과 값을 출력했다.

                byte[] buffer = new byte[1024];   
                DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length);   
                dsock.receive(receivePacket);   
                String msg = new String(receivePacket.getData(),0, receivePacket.getLength());   
                System.out.println("전송받은 문자열 : " + msg );  

패킷을 전송한 클라이언트에게 전송받은 데이터를 그대로 반송하기 위해서 전송 받은 데이터그램으로부터 클라이언트의 IP, 클라이언트의 포트 번호 클라이언트가 전송한 데이터, 클라이언트가 전송한 데이터 길이를 DatagramPacket에 그대로 지정한 후, DatagramSocket에 있는 send() 메소드를 이용해서 전송했다.

                DatagramPacket sendPacket = new DatagramPacket(receivePacket.getData(), receivePacket.getData().length, receivePacket.getAddress(), receivePacket.getPort());   
                dsock.send(sendPacket);   

에코 클라이언트 프로그래밍

import java.net.*;           
import java.io.*;           
x           
public class UDPEchoClient {           
    public static void main(String[] args) {       
        if(args.length != 2){   
            System.out.println("사용법 : java UDPEchoClient ip port");
            System.exit(1);
        }   
        String ip = args[0];   
        int port = 0;   
        try{   
            port = Integer.parseInt(args[1]);
        }catch(Exception ex){   
            System.out.println("port 번호는 양의 정수로 입력하여 주세요.");
            System.exit(1);
        }   
        InetAddress inetaddr = null;   
        try {   
            inetaddr = InetAddress.getByName(ip);
        } catch (UnknownHostException e) {   
            System.out.println("잘못된 도메인이나 ip입니다.");
            System.exit(1);
        }   
        DatagramSocket dsock = null;   
        try{   
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            dsock = new DatagramSocket();
            String line = null;
            while((line = br.readLine()) != null){
                // 전송   
                DatagramPacket sendPacket = new DatagramPacket(line.getBytes(), line.getBytes().length, inetaddr, port);   
                dsock.send(sendPacket);   
                if(line.equals("quit"))   
                    break;
                // 받기   
                byte[] buffer = new byte[line.getBytes().length];   
                DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length);   
                dsock.receive(receivePacket);   
                // 받은 결과 출력.   
                String msg = new String(receivePacket.getData(), 0, receivePacket.getData().length);
                System.out.println("전송받은 문자열 :" + msg);   
            } // while       
            System.out.println("UDPEchoClient를 종료합니다.");       
        }catch(Exception ex){           
            System.out.println(ex);       
        }finally{       
            if(dsock != null)   
                dsock.close();
        }       
    } // main           
} // class               

클라이언트가 접속할 IP와 사용 포트를 외부 인자로 받아들인 후 IP는 InetAddress 객체로, 포트 번호는 정수 값으로 변환시킨다. DatagramPacket에 지정할 서버의 IP 정보가 InetAddress 형태여야 하기 때문이다.

        String ip = args[0];   
        int port = 0;   
        try{   
            port = Integer.parseInt(args[1]);
        }catch(Exception ex){   
            System.out.println("port 번호는 양의 정수로 입력하여 주세요.");
            System.exit(1);
        }   
        InetAddress inetaddr = null;   
        try {   
            inetaddr = InetAddress.getByName(ip);

서버에게 DatagramPacket을 전송하거나 수신하기 위해서 DatagramSocket 객체를 생성한다. 또한 키보드로부터 서버에게 전송할 문자열을 입력받기 위해서, 표준 입력 장치인 System.in을 BufferedReader 형태로 변환 시킨다.

        DatagramSocket dsock = null;   
        try{   
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            dsock = new DatagramSocket();

서버에게 전달할 바이트 배열, 바이트 배열 길이, 서버 IP 정보를 담고 있는 InetAddress 객체, 포트 번호를 DatagramPacket에 지정한 후, DatagramSocket에 있는 send() 메소드를 이용해서 전송한다.

전달할 바이트 배열 값은 키보드로부터 입력받은 문자열 행의 getBytes() 메소드를 이용해서 구했다.

                DatagramPacket sendPacket = new DatagramPacket(line.getBytes(), line.getBytes().length, inetaddr, port);   
                dsock.send(sendPacket);   

서버에게 DatagramPacket을 전송했다면, 다시 반송되는 DatagramPacket을 읽어 들여야 한다. 이를 위해서 DatagramSocket에 있는 receive() 메소드에 비어있는 DatagramPacket 객체를 지정하게 한 후 대기하게 했다.

서버가 DatagramPacket을 전송하게 되면 receive() 메소드는 DatagramPacket을 읽어 들이게 되고, DatagramPacket에게 전달된 바이트 배열을 문자열 형태로 변환한 후 화면에 출력한다.

                byte[] buffer = new byte[line.getBytes().length];   
                DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length);   
                dsock.receive(receivePacket);   
                // 받은 결과 출력.   
                String msg = new String(receivePacket.getData(), 0, receivePacket.getData().length);
                System.out.println("전송받은 문자열 :" + msg);   

에코 클라이언트와 서버 실행

에코 서버 실행 결과

에코 서버 실행 결과

에코 클라이언트 실행 결과

에코 클라이언트 실행 결과