본문 바로가기

Java/기본 개념

네트워크(Network)

▶ 네트워크 (Network)

  • 여러 대의 컴퓨터를 통신 회선으로 연결한 것(홈 네트워크, 지역 네트워크, 인터넷 등)
  • 여러 통신기기를 서로 연결하여 데이터를 손쉽게 주고받거나 자원 등을 공유하기 위해 사용

1) 서버 (Server)와 클라이언트 (Client)

  • 네트워크로 연결된 컴퓨터 간의 관계를 역할(role)로 구분한 개념
  • 서버(Server)는서비스를 제공하는 컴퓨터 또는 프로그램으로,
    클라이언트의 연결을 수락하고 요청 내용을 처리  응답을 보내는 역할
  • 클라이언트(Client)는 서버에 서비스를 요청하여 사용하는 컴퓨터 또는 프로그램으로,
    네트워크 데이터를 필요로 하는 모든 어플리케이션이 해당됨

2) IP 주소

  • 네트워크 상에서 컴퓨터를 식별하는 번호로,
    네트워크 어댑터(랜카드)마다 할당되어 있음

3) 포트 (Port)

  • 같은 컴퓨터 내에서 프로그램을 식별하는 번호로,
    클라이언트 서버연결 요청 시 IP 주소와 포트(Port) 번호를 알아야 

▶ 소켓 (Socket) 프로그래밍

  • 소켓을 이용한 통신 프로그래밍

1) 소켓 (Socket)

  • 프로세스 간의 통신에 사용되는 양쪽 끝단
  • 서버와 클라이언트가 통신하기 위한 매개체

2) 프로토콜 (Protocol)

  • 컴퓨터 간의 정보를 주고 받을 때의 통신방법에 대한 규약으로,
    접속, 전달방식, 데이터의 형식, 검증 방법 등을 맞추기 위한 약속

3) TCP (Transmission Control Protocol)

  • 데이터 전달의 신뢰성을 최대한 보장하기 위한 방식으로 연결 지향형 통신
  • 순차적으로 데이터를 전송하고 확인 및 오류 시 재전송을 함

▶ TCP 소켓 프로그래밍

  • 클라이언트와 서버 간의 1:1 소켓 통신
  • 서버가 먼저 실행되어 클라이언트의 요청을 기다려야 하고,
    서버용 프로그램과 클라이언트용 프로그램을 따로 구현해야 함
  • 자바에서는 TCP 소켓 프로그래밍을 위해 java.net 패키지에서 ServerSocket과 Socket 클래스 제공

1) 서버용 TCP 소켓 프로그래밍 순서 

  • ServerSocket : 서버용 소켓 :  
    - 포트(Port)와 연결되어 외부 요청을 기다리는 역할
       → 클라이언트 요청이 올 경우 이를 수락(accept)하고, 클라이언트가 사용할 수 있는 소켓 생성
       → 서버 소켓과 클라이언트 소켓이 연결되어 데이터 통신이 가능해짐
public void serverStart() {

   // *사용할 변수 미리 선언*
   // 1) 소켓
   ServerSocket seso = null;  // 서버 소켓 저장 변수
   Socket clso = null;        // 클라이언트 소켓 저장 변수
   // 2) 입력스트림
   InputStream is = null;    // 클라이언트 -> 서버 입력용 스트림 변수 (서버 기준)
   BufferedReader br = null; // 입력용 보조 스트림 변수
   // 3) 출력스트림
   OutputStream os = null; // 서버 -> 클라이언트 출력용 스트림 변수 (서버 기준)
   PrintWriter pw = null;  // 출력용 보조 스트림 변수
   
   // 1.서버의 포트번호 정함
   int port = 8500; // port 번호는 0~65535 사이 지정 가능
                    // 단, 1023번 이하는 이미 사용 중인 경우가 많아서 제외

   try {
      // 서버 컴퓨터(내 컴퓨터)의 IP 관련 정보를 얻어옴
      InetAddress inet = InetAddress.getLocalHost();
			
   // 2.서버용 소켓 객체 생성
      seso = new ServerSocket(port); // 서버용 소켓을 생성하여 포트 결합
			
   // 3.클라이언트쪽에서 접속요청이 오길 기다림
   // - 서버용 소켓은 생성되면 클라이언트 요청이 오기 전까지
   //   다음 코드를 수행하지 않고 대기하고 있음
      System.out.println("[Server]");
      System.out.println("클라이언트의 요청을 기다리고 있습니다...");
			
   // 4.접속요청이 오면 요청 수락 후 해당 클라이언트에 대한 소켓 객체 생성
   // -> 요청을 수락하면 자동으로 Socket 객체가 얻어와짐
      clso = seso.accept(); 
			
   // 접속한 클라이언트의 IP를 얻어와 출력
      String clientIP = clso.getInetAddress().getHostAddress();
      System.out.println(clientIP + "가 연결을 요청함");
			
   // 5.연결된 클라이언트와 입출력 스트림 생성
      is = clso.getInputStream();  // 클라이언트 -> 서버 입력
      os = clso.getOutputStream(); // 서버 -> 클라이언트 출력
			
   // 6.보조 스트림을 통해 성능 개선
      br = new BufferedReader( new InputStreamReader(is) );
      // InputStreamReader : 문자 기반 스트림과 바이트 기반 스트림 연결에 사용되는 스트림
      pw = new PrintWriter(os);
			
   // 7.스트림을 통해 읽고 쓰기
   // 7-1) 서버 -> 클라이언트에게 출력(메세지 전송)
      pw.println("[서버 접속 성공]");
      pw.flush(); // 스트림(버퍼)에 기록된 내용을 밀어내는 코드
                  // -> 미작성 시 클라이언트쪽으로 출력 X
   // 7-2) 클라이언트 -> 서버에게 입력(메세지 전송 받기)
      String clientMessage = br.readLine(); // 클라이언트 메시지 한 줄을 읽어옴
      System.out.println(clientIP+"로부터 받은 메세지 : "+clientMessage);

   } catch (IOException e) {
        e.printStackTrace(); // 예외 추적
			
   } finally { // try 구문에서 예외 발생 여부 관계 없이 무조건 수행
   // 8.통신 종료			
   // 사용한 스트림, 소켓 자원을 모두 반환(close)
   // -> 메모리 누수 관리
   // 보통 소켓, 스트림 생성 역순으로 close() 구문을 작성
        try {
            // 보조 스트림 close 시 연결된 기반 스트림(is,os)도 같이 close됨
            if(pw != null) pw.close(); // + os.close()
            if(br != null) br.close(); // + is.close()
				
            if(clso != null) clso.close();
            if(seso != null) seso.close();
				
        } catch (IOException e) {
             e.printStackTrace();
        }
   }
}

2) 클라이언트용 TCP 소켓 프로그래밍 순서

public class TCPClient {
   public void clientStart() {
   /* 필요한 변수 선언 */
      Socket clso = null; // 서버와 연결할 클라이언트용 소켓을 저장할 변수

      BufferedReader br = null; // 서버 -> 클라이언트로 읽어오는 보조 스트림

      PrintWriter pw = null; // 클라이언트 -> 서버로 출력하는 보조 스트림
   
   // 1. 서버의 IP 주소와 서버가 정한 포트 번호를 매개변수로 하여 클라이언트용 소켓 객체 생성
      String serverIP = "127.0.0.1"; // loop back ip(내 컴퓨터를 가리키는 ip주소)
      int port = 8500; // 서버 소켓이 기다리고 있는 포트 번호 작성

      try {
   // 2. 서버와의 입출력 스트림 오픈 -> 먼저 소켓이 필요함
         System.out.println("[Client]");

         clso = new Socket(serverIP,port); // 클라이언트용 소켓 객체(서버 IP주소,포트) 생성

   // 3. 보조 스트림을 통해 성능 개선
   // 2 & 3번 동시 진행
         br = new BufferedReader( new InputStreamReader( clso.getInputStream()));

         pw = new PrintWriter( clientSocket.getOutputStream());

   // 4. 스트림을 통해 읽고 쓰기
   // 4-1) 서버 접속 성공 시 
   //	   서버가 출력한 "[서버 접속 성공]" 메시지 읽어오기
         String message = br.readLine();
         System.out.println("서버로부터 받은 메시지 : " + message);

   // 4-2) 클라이언트 -> 서버로 메시지 전송
         Scanner sc = new Scanner(System.in);
         System.out.print("입력 : ");
         String input = sc.nextLine();

         pw.println(input);
         pw.flush();

      } catch (IOException e) {
           e.printStackTrace();

      } finally {
   // 5. 통신 종료
              try {
                   if(br != null) br.close();
                   if(pw != null) pw.close();
                   if(clso != null) clso.close();

              } catch (IOException e) {
                   e.printStackTrace();
              }
        }
   }
}

 

'Java > 기본 개념' 카테고리의 다른 글

변수(Variable)  (0) 2024.12.16
프로그래밍 기초  (0) 2024.12.16
컬렉션(Collection)  (2) 2024.11.17
스레드(Thread)  (0) 2024.11.17
입출력 (IO_Input / Output)  (3) 2024.11.17