SSISO Community

시소당

양방향 통신

클라이언트에서  서버로,  그리고  서버에서  클라이언트로  양방향으로  통신  가능한  서버와  클라이언트를  제작해  보자.  클라이언트에서  파일이름(문자열)을  서버로  전송하면,  서버는  파일의  내용(문자열)을  클라이언트로  보내도록  해보자.  

이번에는  BufferedReader와  PrintWriter  대신에  DataInputStream과  DataOutputStream을  사용해  보자.  DataInutStream의  readUTF와  DataOutputStream의  writeUTF를  데이터  입출력할  때  사용한다.  아래  그림은  여기서  작성할  서버/클라이언트  프로그램의  데이터  입출력을  나타낸  것이다.  

[그림  21-8]  클라이언트  ↔  서버
  

파일  전송  서버

파일  전송  서버라고  해서  특별한  것은  없다.  클라이언트가  요청하는  텍스트  파일을  문자열로  전송하는  간단한  서버이다.  클라이언트의  신호를  받으면  응답  신호를  클라이언트로  보내지만  클라이언트의  신호가  없으면  서버의  응답도  없다.

while(true){

    ...=  reader.readUTF();                  //  클라이언트의  신호를  받는다.

  

    writer.writeUTF(...);                      //  클라이언트로  응답을  보낸다.

    writer.flush();

    ...

}

  

이  서버  프로그램은  하나의  클라이언트만  지원한다.  다중  클라이언트를  지원하는  서버에  비해  구조가  단순해서  구현하기  쉽다.

  

Server3.java


  

import  java.net.*;

import  java.io.*;

public  class  Server3{

    private  DataInputStream  reader;                  //  입력  스트림

    private  DataOutputStream  writer;                //  출력  스트림

    private  ServerSocket  server;                        //  서버소켓

    private  Socket  socket;                                    //  소켓

    public  Server3(){}

    void  startServer(){                                            //  서버를  동작시킨다.

        try{

            server=new  ServerSocket(7777);

            System.out.println("서버소켓이  생성되었습니다.");

            while(true){

                System.out.println("클라이언트를  기다립니다.");

                socket=server.accept();

                System.out.println("클라이언트와  연결되었습니다.");

  

                //  socket의  입력  스트림과  출력  스트림을  얻는다.

                reader=new  DataInputStream(socket.getInputStream());

                writer=new  DataOutputStream(socket.getOutputStream());

  

                getCommand();                                        //  클라이언트와  통신한다.

            }

        }catch(Exception  e){

            System.out.println(e);    

        }

    }

  

    //  클라이언트가  요청한  파일을  전송하는  메소드

    void  getCommand(){

        try{

            while(true){

                String  fileName=reader.readUTF();                      //  파일이름을  얻는다.

  

                //  해당  파일의  내용을  클라이언트  측의  소켓으로  전송한다.

                writer.writeUTF(getFileInfo(fileName));

                writer.flush();

  

                System.out.println(fileName  +"의  정보  전송  완료");

            }

        }catch(Exception  e){

        }finally{

            System.out.println("클라이언트와의  접속이  끊겼습니다.");

            try{

                if(reader!=null)  reader.close();

                if(writer!=null)  writer.close();

                if(socket!=null)  socket.close();

                reader=null;  writer=null;  socket=null;

            }catch(IOException  ie){}

        }

    }

    

    //  fileName에  해당하는  파일의  내용을  반환하는  메소드

    String  getFileInfo(String  fileName){

        String  fileInfo="";

        try{

            FileReader  fr=new  FileReader(fileName);

            BufferedReader  br=new  BufferedReader(fr);

            String  temp;

            while((temp=br.readLine())!=null)

                fileInfo+=  temp+"\n";

            br.close();

        }catch(FileNotFoundException  fe){

            fileInfo="파일이  없습니다.";

        }catch(IOException  ie){}

        return  fileInfo;

    }

  

    public  static  void  main(String[]  args){

        Server3  server=new  Server3();

        server.startServer();

    }

}

  

  

  

파일  수신  클라이언트

앞에서  작성한  서버에  대응하는  클라이언트를  작성하자.  이  프로그램은  파일이름(문자열)을  서버로  보내고  서버의  응답(파일의  내용)을  받아서  화면에  출력할  것이다.  즉,  서버로  신호를  보내고  서버의  응답을  기다린다.

  

{

    writer.writeUTF(sendBox.getText());        //  서버로  신호를  보낸다.

    writer.flush();

  

    String  fileInfo=reader.readUTF();              //  서버의  응답  메시지를  받는다.

  

    msgView.append(fileInfo);                            //  파일의  내용을  보여준다.

}

  

[그림  21-9]  서버(위)와  클라이언트(아래)의  실행화면

  

  

Client3.java


  

import  java.awt.*;

import  java.net.*;

import  java.io.*;

import  java.awt.event.*;

public  class  Client3  extends  Frame{

    private  TextArea  msgView=new  TextArea();          //  파일을  보여주는  텍스트영역

    private  TextField  sendBox=new  TextField();        //  파일이름을  입력하는  텍스트필드

    private  DataInputStream  reader;                              //  입력  스트림

    private  DataOutputStream  writer;                            //  출력  스트림

    Socket  socket;                                                              //  소킷

    public  Client3(String  title){                                        //  생성자

        super(title);

        msgView.setEditable(false);

        add(msgView,"Center");

        add(sendBox,"South");

  

        //  sendBox  액션  이벤트  처리

        sendBox.addActionListener(new  ActionListener(){

            public  void  actionPerformed(ActionEvent  ae){

                try{

  

                    //  파일이름을  서버로  전송한다.

                    writer.writeUTF(sendBox.getText());

                    writer.flush();

      

                    //  소켓의  입력  스트림으로부터  파일의  내용을  얻는다.

                    String  fileInfo=reader.readUTF();

                    msgView.setText("<  "  +  sendBox.getText()+"의  내용  >\n\n");

                    msgView.append(fileInfo);

  

                    sendBox.setText("");

                }catch(Exception  ie){}

            }    

        });

        pack();

    }

    private  void  connect(){                                    //  서버와  연결하는  메소드

        try{

            msgView.append("서버와의  연결을  시도합니다.\n");

            socket=new  Socket("127.0.0.1",  7777);

            msgView.append("연결  완료...  보고싶은  파일의  이름을  입력하세요.\n");

  

            //  소켓의  입·출력  스트림을  얻는다.

            reader  =  new  DataInputStream(socket.getInputStream());

            writer  =  new  DataOutputStream(socket.getOutputStream());

        }catch(Exception  e){

            msgView.append("연결  실패..");

        }

    }

    public  static  void  main(String[]  args){

        Client3  client=new  Client3("서버  시스템  파일  보기");

        client.setVisible(true);

        client.connect();      //  서버와  연결한다.

    }

}

출처  :  http://java.pukyung.co.kr/Lecture/Chapter21.php

1938 view

4.0 stars