KyungHwan's etc.

자바(JAVA) Sokect 통신 본문

Java

자바(JAVA) Sokect 통신

KyungHwan_0 2018. 6. 22. 10:26

자바(JAVA) Sokect 통신

우리가 통신할 때에 전송할 패킷(데이터)이 컴퓨터에서 랜 케이블로 나간다. 그리고 그 랜 케이블에서 라우터, DNS 순으로 패킷이 이동한다. 그 이동된 패킷들은 다시 라우터를 타고 목표로 하는 컴퓨터로 전송이 돼서 프로그램을 찾아 통신이 이루어진다. 그런데 우리는 이런 일련의 전송형태를 다 설정을 하지 않는다.이 통신 형태들은 OS 단계에서 설정되고(OSI 7계층), 프로그램을 작성할 때는 소켓, 즉 「그 모든 설정 위에 꽂아서 쓴다」라는 개념으로 소켓을 통해서 통신이 된다.

링크 - [위키백과] OSI 모형

소켓의 흐름

소켓은 서버가 로컬 IP를 가지고 Port를 열고(Bind) 클라이언트 접속을 기다린다(Listen).

그리고 클라이언트는 서버의 IP주소와 Port로 접속(Connection)해서 연결되면, 서버와 클라이언트는 Send, Recieve형태로 패킷을 주고받다가, 서로의 통신이 끝나면 close로 접속을 끊는다.

출처 - http://jkkang.net/unix/netprg/chap2/net2_1.html

서버측

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
   public static void main(String... args){
       //자동 close
       try(ServerSocket server = new ServerSocket()){
           // 서버 초기화
           InetSocketAddress ipep = new InetSocketAddress(9999);
           server.bind(ipep);
           
           System.out.println("Initialize complate");
           
           //LISTEN 대기
           Socket client = server.accept();
           System.out.println("Connection");
           
           //send,reciever 스트림 받아오기
           //자동 close
           try(OutputStream sender = client.getOutputStream();
               InputStream reciever = client.getInputStream();){
               //클라이언트로 hello world 메시지 보내기
               //11byte 데이터
               String message = "hello world";
               byte[] data = message.getBytes();
               sender.write(data, 0, data.length);
               
               //클라이언트로부터 메시지 받기
               //2byte 데이터
               data = new byte[2];
               reciever.read(data, 0, data.length);
               
               //수신 메시지 출력
               message = new String(data);
               String out = String.format("recieve - %s", message);
               System.out.println(out);
          }
      }catch(Throwable e){
           e.printStackTrace();
      }
  }
}

위 소스를 보면면 서버에서 9999라는 포트를 열고 accept 함수에서 대기상태에 들어갔다.


콘솔 상태에서 Port Listen 상태를 확인하니 「9999」가 열려 있는 것을 확인했다.

클라이언트측

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

public class Client {
   public static void main(String... args){
       //자동 close
       try(Socket client = new Socket()){
           //클라이언트 초기화
           InetSocketAddress ipep = new InetSocketAddress("127.0.0.1", 9999);
           //접속
           client.connect(ipep);
           
           //send,reciever 스트림 받아오기
           //자동 close
           try(OutputStream sender = client.getOutputStream();
               InputStream receiver = client.getInputStream();){
               //서버로부터 데이터 받기
               //11byte
               byte[] data = new byte[11];
               receiver.read(data,0,11);
               
               //수신메시지 출력
               String message = new String(data);
               String out = String.format("recieve - %s", message);
               System.out.println(out);
               
               //서버로 데이터 보내기
               //2byte
               message = "OK";
               data = message.getBytes();
               sender.write(data, 0, data.length);
          }
      }catch(Throwable e){
           e.printStackTrace();
      }
  }
}

실행하니 결과는 Hello world가 나왔다. 서버측의 콘솔을 확인하니 Connect, recieve - OK 라는 메시지를 받았다.

흐름에 대해 설명을 하면 먼저 서버가 9999 포트로 Listen 상태로 클라이언트를 대기한다. 그런 후 클라이언트는 9999포트로 접속한다.이때 클라이언트는 서버로부터 메시지 대기를 하고 서버는 클라이언트로 「Hello world」의 11byte 메시지를 보낸다.그리고 서버는 클라이언트로부터 메시지를 대기하고 클라이언트는 서버로 「OK」의 2byte 메시지를 보낸다. 클라이언트로부터 메시지를 받고 종료한다.

피시 한 대로 테스트했지만 테스트 환경이 허락되면 피시 두 대 이상으로 테스트하면 통신이 이루어지는 것을 확인할 수 있다.

Reference

http://nowonbun.tistory.com/315

Comments