SSISO Community

시소당

단방향 통신

클라이언트에서  서버로  문자열을  송신하는  프로그램을  제작해보자.  클라이언트에서  서버로  단방향  통신만  가능하다.  클라이언트  측의  소켓과  서버  측의  소켓이  연결되었을  때  클라이언트  측  소켓의  출력  스트림으로  데이터를  전송하면  서버  측  소켓의  입력  스트림으로부터  데이터를  수신하면  된다.  이때  채팅  프로그램과  같이  한  라인  단위로  입·출력하기  위해  자주  사용되는  PrintWriter와  BufferedReader를  이용하자.  다음  그림은  클라이언트에서  서버  쪽으로  데이터의  흐름을  표현한  것이다.  

[그림  21-6]  클라이언트  ->  서버  

PrintWriter  대신에  BufferedWriter를  사용할  수도  있으나  PrintWriter는  자동  flush가  되기  때문에  더  좋다.  flush기능을  사용하지  않으면  데이터가  제때  송신하지  않을  수  있으므로  주의해야할  것이다.  

서버의  소스파일  이름은  "Server2.java"이고,  클라이언트의  소스파일  이름은  "Client2.java"로  하여  실제로  구현해  보자.
  

문자열  수신  서버

단일  클라이언트를  위한  서버는  그렇게  복잡하지  않다.  제작할  서버  프로그램은  클라이언트  측  소켓과  연결된  소켓으로부터  문자열을  읽어와  화면에  그대로  보여준다.  그러나  클라이언트  측으로는  어떤  데이터도  전송하지  않는다.

  

서버는  다음과  같은  과정을  반복한다.

  

1.  클라이언트를  기다린다.

2.  클라이언트와  연결한다.

3.  클라이언트가  연결을  끊기  전까지  문자열을  수신한다.

4.  클라이언트가  연결을  끊는다.

5.  1번을  실행한다.

  

  

클라이언트와  연결된  소켓의  입력  스트림을  얻는  과정은  다음과  같다.

  

Socket  socket=server.accept();                                      //  클라이언트와  연결된  소켓

InputStream  is=socket.getInputStream();                //  소켓의  InputStream을  얻는다.

InputStreamReader  isr=new  InputStreamReader(is);

BufferedReader  reader=  new  BufferedReader(isr);        //  캐릭터  스트림

  

  

다음  문자열  수신  서버의  소스이다.

  

Server2.java


  

import  java.net.*;

import  java.io.*;

public  class  Server2{

    private  BufferedReader  reader;          //  입력을  담당한다.

    private  ServerSocket  server;                //  서버소켓

    private  Socket  socket;                          //  소켓

    public  Server2(){}                                  //  디폴트  생성자

    void  startServer(){                                  //  서버  실행  메소드

        try{

            server=new  ServerSocket(7777);                                      //  서버소켓을  생성한다.

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

            while(true){

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

  

                socket=server.accept();          //  클라이언트가  접속하면  socket과  연결한다.

  

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

  

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

                reader=new  BufferedReader(

                                                new  InputStreamReader(  socket.getInputStream()  ));

  

                  getMessage();        //  클라이언트가  보낸  데이터를  읽어서  화면에  출력한다.

            }

        }catch(Exception  e){

            System.out.println(e);

        }

    }

    void  getMessage(){        //  소켓으로부터  메시지를  읽는다.

        try{

            while(true){                //  무한  루프

  

                //  소켓의  입력  스트림으로부터  데이터를  한  라인을  읽어서  화면에  출력한다.

                System.out.println("클라이언트:  "+reader.readLine());

  

            }

        }catch(Exception  e){

        }finally{

            System.out.println("클라이언트가  연결을  끊었습니다.");

            try{

                if(reader!=null)  reader.close();              //  소켓의  입력  스트림을  닫는다.

                if(socket!=null)  socket.close();            //  소켓을  닫는다.

            }catch(IOException  ie){}

        }

    }

    public  static  void  main(String[]  args){

        Server2  server=new  Server2();

        server.startServer();

    }

}

  

  

  

문자열  전송  클라이언트

클라이언트의  소켓은  서버와  연결하고  소켓의  출력  스트림으로  데이터를  송신한다.  코딩의  수고가  있기는  하지만  클라이언트  프로그램은  AWT로  제작해보자.

  

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

  

  

Client2.java


  

import  java.awt.*;

import  java.net.*;

import  java.io.*;

import  java.awt.event.*;

public  class  Client2  extends  Frame{

    private  TextArea  msgView=new  TextArea();        //  메시지를  보여주는  텍스트영역

    private  TextField  sendBox=new  TextField();        //  문자열을  입력하는  텍스트필드

    private  PrintWriter  writer;                                            //  소켓의  출력  스트림

    Socket  socket;                                                                //  소켓

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

        super(title);

        msgView.setEditable(false);        //  텍스트영역을  사용자가  편집할  수  없도록  한다.

        add(msgView,"North");                  //  컴포넌트  배치

        add(sendBox,"South");

  

        //  sendBox에  문자열을  입력하고  엔터를  누르면

        //  문자열을  전송한다.

        sendBox.addActionListener(new  ActionListener(){

            public  void  actionPerformed(ActionEvent  ae){

                

                //  sendBox의  문자열을  출력  스트림으로  전송한다.

                writer.println(sendBox.getText());

                

                    //  msgView에  보낸  문자열을  추가한다.

                msgView.append(sendBox.getText()+"\n");

  

                    //  sendBox의  내용을  지운다.

                sendBox.setText("");

            }    

        });

        pack();                                                                    //  프레임의  크기를  자동으로  맞춘다.

    }

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

        try{

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

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

            msgView.append("연결되었습니다.  전송할  문자열을  입력하세요.\n");

  

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

            writer  =  new  PrintWriter(socket.getOutputStream(),  true);

  

        }catch(Exception  e){

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

        }

    }

    public  static  void  main(String[]  args){

        Client2  client=new  Client2("서버로  데이터  보내기");

        client.setVisible(true);

        client.connect();

    }

}

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

1303 view

4.0 stars