운영체제 - 프로세스간 통신( IPC )

TopOfTheHead·2025년 7월 22일

운영체제

목록 보기
10/24

프로세스Concurrently하게 처리될 경우 프로세스Independent하거나, Cooperative하게 처리된다.

  • 프로세스Independent한 경우
    。다른 프로세스와 데이터를 공유하지 않는 프로세스
    ▶ 스케듈링만 잘하면 문제가 발생되지 않는다.

  • 프로세스Cooperative한 경우
    。다른 프로세스와 데이터를 공유하는 프로세스
    ▶ 다른 프로세스에 영향을 주거나 받을 수 있으며 주로 문제가 발생하는 유형

    。대표적으로 부모 프로세스 , 자식 프로세스가 존재

프로세스 간 통신 ( IPC : Inter-Process Communication )
OS 상에서 Concurrently하게 실행중인 프로세스 간 서로 데이터 및 정보를 공유하기 위한 Mechanism

프로세스Cooperative한 경우 데이터를 주고받는 IPC 기능이 필요한 경우 IPC Mechanism( ex. Shared Memory or Message Passing )으로 IPC를 구현

IPC를 구현한 IPC System은 컴퓨터 내부 프로세스 간 통신( ex. Pipe ) / 네트워크 상 통신( ex. Socket ) 등이 존재.

IPC의 두가지 주요 메카니즘
。아래 두가지 기법으로 IPC를 구현

  • 공유메모리( Shared Memory )
    프로세스특정 메모리 공간( = Shared Memory )을 서로 공유하여 데이터를 주고받는 방식으로 IPC를 구현
    ▶ 주로 생산자 프로세스소비자 프로세스간 데이터 교환 시 버퍼로서 활용

    Shared Memory메모리 영역으로서 범위가 제한되어있음.
    bounded buffer

    。모든 프로세스에서 접근이 가능

    메모리 영역상에서 공유하는 경우 개발자가 Shared Memory에 접근 및 상호작용하는 코드를 일일이 명시적으로 하드코딩하여 작성해야하는 단점 존재
    • 버퍼 ( Buffer )
      。처리속도가 다른 프로세스 간 상호작용하는 데이터를 저장하는 임시저장공간
      ▶ 두 프로세스의 전송률을 비슷하게 조정하는 버퍼링에 활용


  • 메세지전달( Message Passing )
    송신자 프로세스수신자 프로세스메모리 영역Message Queue를 통해 서로 Message를 주고받는 방식으로 IPC를 구현

    OSIPC 용도의 API( send() , receive() )를 기본 제공 및 관리하므로 Shared Memory처럼 개발자가 직접 상호작용하는 코드를 하드코딩할 필요 없이 간편하게 API만 활용

    프로세스간 통신을 구현하기위해 우선 프로세스Communication Link가 사전에 설정되어야하며 이후 send()receive()의 두 API를 통해 Message-Passing을 수행

    통신링크 ( Comm.link : Communication Link )
    Message-Passing 방식으로 IPC를 수행하기 위해 사전에 설정되어야하는 링크
    ▶ 구현된 이후 API를 통해 메시지를 주고받음

    Comm.link 구현 옵션 :
    1) Direct / Indirect Communication
    2) Synchronous / Asynchronous Communication
    3) Automatic or explicit Buffering

    ex ) Direct하고 , Synchronous 하며 AutomaticCommunication Link 구현

    • Direct or Indirect Communication
      • 직접 통신 연결 ( Direct Communication )
        。메세지를 주고받을 두개의 수신자 프로세스송신자 프로세스의 각각의 프로세스 이름을 명시적으로 설정하여 직접적인 통신을 수행

        。통신을 수행할 2개의 프로세스 이름만 알면 프로세스간 통신 링크를 자동으로 구축
        ▶ 구현된 통신 링크는 오직 연결된 두 프로세스 와의 상호작용만 가능

        프로세스 이름이 변경될 경우 문제가 생기는 단점이 존재
        Mailbox를 활용한 간접 통신 연결을 활용

        API 종류
        send( P, 메시지 ) : P 프로세스에게 메세지를 전송

        receive( Q, 메시지 ) : Q 프로세스으로부터로부터 메세지를 수신



      • 간접 통신 연결 ( Indirect Communication )
        。임의의 프로세스간 메세지 전달 시 Mailbox( = port )를 통해 메세지를 송신 및 수신받는 구조

        。통신을 수행할 임의의 프로세스들이 서로 동일한 Shared Mailbox로 연결되어 공유 시 통신링크를 구축할 수 있다.
        직접 통신 연결과 다르게 구현된 통신링크메일박스를 통해 2개 이상의 프로세스간 상호작용이 가능

        。각 통신링크는 하나의 메일박스에 대응하며 각 프로세스 사이에 여러개의 통신링크를 구현할 수 있음
        ▶ 복잡한 통신링크를 구현할 수 있다

        OS프로세스에게 다음 메카니즘을 기본적으로 제공.
        메일박스 생성 및 삭제 / 메일박스를 통한 메시지 송수신
        ▶ 다음 메카니즘을 활용하여 OS에 의해 Port( = Mailbox )가 자동으로 관리되도록 설정
        • Mailbox ( = Port )
          。복수의 프로세스로 부터 메시지를 수신받아 저장하거나 송신하여 삭제하는 공유 저장소 용도의 객체

        • API 종류
          send( A, 메시지 ) : A 메일박스에게 메세지를 전송

          receive( A, 메시지 ) : A 메일박스으로부터로부터 메세지를 수신


    • Synchronous or Asynchronous Communication
      Blocking : Synchronous , Non-blocking : Asynchronous
      。다음 4가지 방식을 조합하여 IPCMessage Passing 방식을 구현
      • Blocking I/O : 동기
        。메세지 송수신 작업이 완료될때까지 송/수신 프로세스를 대기해야하므로 비효율적이지만 데이터의 안정성이 높음

        Blocking Send
        송신자 프로세스가 메세지 전송 시 해당 메세지가 수신할때까지 Block되어 대기큐에 전송되어 Waiting 상태로 대기
        메세지가 수신될때까지 다른 프로세스가 CPU Scheduler에 의해 선택되어 디스패처에 의해 CPU가 할당되어 실행

        Blocking Receive :
        수신자 프로세스는 메세지를 수신할때까지 대기큐에서 Waiting 상태로 대기

      • Non-Blocking I/O : 비동기
        。메세지 송수신 작업여부에 관계 없이 송/수신 프로세스를 계속 실행할 수 있어 효율적이지만 중간에 프로세스의 연결이 끊길 경우 전송중인 데이터가 불완전하게 전송되므로 불안정

        Non-Blocking Send
        송신자 프로세스가 메세지 전송 시 메세지 수신여부에 관계없이 계속 Running 상태를 유지

        Non-Blocking Receive
        수신자 프로세스는 메세지 수신여부에 관계없이 Running 상태로서 계속 Valid Message 또는 Null Message를 내보냄.
        ▶ 내보내는 메세지에 따라 수신여부를 판단.

생산자-소비자 문제 ( Producer-Consumer Problem )
OS 상에서 여러 프로세스가 공유자원( ex. 버퍼 )에 접근하여 상호작용 시 발생하는 동기화( Syncronization ) 문제
Cooperative프로세스간 주로 발생하는 문제

생산자가 정보를 생성하면 소비자가 해당 정보를 소비하는 형태에서 생산속도와 소비속도의 차이로 인해 발생하는 문제
ex1 ) CompilerAssembly Code를 생성 시 Assembler가 해당 코드를 소비하여 machine code를 생성 시 발생하는 문제
ex2 ) 웹 서버HTML문서 생성 시 웹 브러우저가 해당 웹 주소로 접근하여 시각화하여 소비하는 경우 발생하는 문제

  • IPC : Shared-Memory 기법으로 문제 해결 시
    생산자 프로세스소비자 프로세스 둘다 Concurrently하게 실행할 경우 메모리 영역Shared-MemoryShared Buffer로서 활용하여 동기화를 원활하게하여 데이터를 공유하도록 설정
    장치 컨트롤러데이터 버퍼링과 유사

    Shared Buffer원형버퍼로 구현

    생산자 프로세스Shared Buffer데이터를 채우고, 소비자 프로세스Shared Buffer를 비우면서 상호작용

    。이때 Shared-Memory메모리 영역으로서 범위가 제한된 Bounded Buffer이므로 Bounded Buffer Problem이 발생할 수 있음
    Buffer가 가득찬 경우 생산자 프로세스의 상태를 Waiting 변경 및 Buffer가 빈 경우 소비자 프로세스의 상태를 Waiting으로 설정

    메모리 영역을 사용하는 방식이므로 개발자가 코드를 일일이 명시적으로 하드코딩하여 작성해야하는 단점 존재
    메세지전달 방식을 사용하는 이유 중 하나

    코드구현
    Shared Buffer 초기화
    전역변수로 작성하여 각 프로세스에서 접근하도록 설정

    #include <stdio.h>
    #include <stdbool.h> 
    // 버퍼 초기화
    #define BUFFER_SIZE 10
    typedef struct {
      // 버퍼 요소를 구성할 item 구조체 선언
    } item;
    // 버퍼 배열 초기화
    item buffer[BUFFER_SIZE];
    // 버퍼 인덱스 초기화
    int in = 0;
    int out = 0;

    생산자 프로세스 정의

    // 생산자 프로세스 정의
    item next_produced;
      while(true){
        // 버퍼가 가득찬 경우 아무 작업도 하지않기
        while(( in + 1 ) % BUFFER_SIZE == out) ; 
        //
        // 버퍼가 빈 경우 item input
        buffer[in] = next_produced;
        in = (in + 1) % BUFFER_SIZE;
      };

    소비자 프로세스 정의

    // 소비자 프로세스 정의
      item next_consumed;
      while (true) {
        // 버퍼가 비어있는경우 아무 작업하지 않기
        while ( in == out ) ; 
        next_consumed = buffer[out];
        out = (out + 1) % BUFFER_SIZE;
      }

IPC Mechanism으로 구현된 대표적인 IPC System
Shared MemoryPOSIX Shared Memory
Message PassingPipes

  • POSIX Shared Memory
    Shared Memory Mechanism으로 구현된 IPC System

    memory-mapped files을 통해 HDD에 저장된 파일메모리에 Mapping 후 해당 영역을 Shared Memory로 활용

    Shared Memory 방식이므로 개발자가 shm_open() , shm_unlink() 등 데이터 전달에 대해 일일이 하드코딩할 코드가 많다
    • POSIX ( Portable Operating System Interface For Unix )
      。서로 다른 UNIX OS 간 호환성을 위해 공통 API를 책정한 Application Interface 규격
      POSIX를 준수하는 UNIX OS는 다른 UNIX OS와 호환

    • MMF ( Memory Mapped Files )
      OS에서 HDD에 저장된 파일메모리에 Mapping하여 파일메모리의 일부로 간주하여 접근할 수 있도록 하는 기능


  • 파일이 매핑된 메모리 주소공간에 POSIX Shared Memory 생성

    1) POSIX Shared Memory 객체 생성
    fd=shm_open(name, O_CREAT | ORDWR, 0666);

    2) 객체의 byte 기준 크기 설정
    ftruncate(fd, 4096)
    4096 Byte로 크기 설정

    3) POSIX Shared Memory 객체를 파일메모리 상 주소공간으로 Mapping
    mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)
    • shm_open()
      POSIX Shared Memory 객체를 생성하거나 기존 객체를 open하는 역할을 수행

      。생성된 객체의 크기는 0이므로 크기 설정이 필요.

    • ftruncate(fd, size)
      。생성된 객체의 크기를 Byte 단위로 설정

    • mmap()
      POSIX Shared Memory 객체를 메모리 영역으로 Mapping

    • PROT ( Protection Flags )
      메모리 보호 목적으로 Mapping메모리 영역에 대해 어떠한 접근을 허용할 것인지 지정하는 인자

      PROT 종류

      • PROT_READ
        메모리 페이지를 읽기 가능하게 설정

      • PROT_WRITE
        메모리 페이지를 쓰기 가능하게 설정

      • PROT_EXEC
        메모리 페이지에서 기계어 실행이 가능하도록 허용

      • PROT_NONE
        메모리 페이지에 어떠한 접근을 모두 금지


    • flags
      Mapping메모리 영역의 종류, 공유 방식, 주소지정방식을 정의하는 인자
      • MAP_SHARED
        프로세스Shared Memory 객체에 대해 해당 메모리 영역에 대한 WRITE 작업을 허용


  • POSIX Shared-Memory API 구현
    • Producer Process
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/shm.h>
    #include <sys/stat.h>
    #include <sys/mman.h>
    int main(){
      // 생성할 POSIX shared memory 객체의 크기 , 이름 설정
      const int SIZE = 4096; 
      const char *name = "OS"; 
      //
      // 전달할 메시지 설정
      const char *message_0 = "Hello, ";
      const char *message_1 = "Shared Memory!\n";
      //
      int shm_fd; // shared memory의 file descriptor 정의
      char *ptr; // shared memory 포인터
      //
      // POSIX Shared Memory 객체 생성
      shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
      //
      // 객체의 크기 설정
      ftruncate(shm_fd, SIZE);
      //
      // 객체의 Mapping 수행
      ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
      //
      // POSIX Shared Memory 객체로 메세지 공유
      sprintf(ptr, "%s" , message_0);
      ptr += strlen(message_0);
      sprintf(ptr, "%s", message_1);
      ptr += strlen(message_1);
    }

    。이후 터미널에 gcc 파일명.c -lrt로 컴파일
    -lrt : librt 라이브러리에 정의된 함수를 활용하기위해 해당 라이브러리를 링크

      • librt
        POSIX 표준 中 Real-time Extension을 제공하는 라이브러리

        POSIX Shared Memory 를 구현하는 shm_open() 등의 함수는 librt에 구현되어있어 -lrt 없이 컴파일 시 Link Error 발생.


    • Consumer Process
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <fcntl.h>
    #include <sys/shm.h>
    #include <sys/stat.h>
    #include <sys/mman.h>
    int main(){
      const int SIZE = 4096; 
      const char *name = "OS"; 
      int shm_fd; 
      char *ptr; 
      //
      // 읽기 목적의 POSIX Shared Memory 객체 생성
      shm_fd = shm_open(name, O_RDONLY,0666);
      //
      // POSIX Shared Memory 객체 Mapping
      ptr = (char *)mmap(0, SIZE, PROT_READ , MAP_SHARED, shm_fd, 0);
      // 객체로부터 읽기
      printf("%s", (char *)ptr);
      // 객체 삭제하기
      shm_unlink(name);
      return 0;
    }


    。 메세지가 POSIX Shared Memory에 송신 및 수신이 정상적으로 수행됨을 관측가능.

    소비자 프로세스에서 shm_unlink()를 통해 메모리 공간상에 Mapping된 shared memory가 삭제됨.
    ▶ 한번 더 호출하는 경우 해당 객체를 찾을 수 없음

Pipes
。초창기 UNIX System에서 활용된 Message Passing으로 구현된 IPC Mechanism

。2개의 프로세스 간 통신으로 데이터를 주고받는 통로
파이프Message Box( = Port) 역할을 수행

。동일한 HW Device프로세스 간 통신 시 사용.
Client-Server System네트워크로 연결된 다른 컴퓨터의 프로세스 접근 시 Pipe 대신 Socket 사용

  • Pipe 구현 시 고려사항
    • 단방향 ( Unidirectional ) / 양방향 ( Bidirectional )

      양방향인 경우 Half Duplex / Full Duplex
      반이중 ( Half Duplex ) :
      한번에 한 방향으로만 데이터의 송수신이 가능한 것

      전이중 ( Full Duplex ) :
      데이터를 동시에 송수신이 가능



    • 통신을 수행하는 프로세스Relationship 존재 여부
      Named PipeRelationship 없이 사용가능
      ex ) 부모 / 자식 프로세스 관계

    • 네트워크 상 통신 여부
      네트워크로 연결된 다른 컴퓨터의 프로세스 접근 시 Pipe 대신 Socket 사용


  • Pipe의 종류
    파이프Message Box( = Port) 역할을 수행
    • 일반 파이프( Ordinary Pipe ) = 익명 파이프 ( Anonymous Pipe )
      생산자 소비자 형태에서 두 프로세스간 통신을 수행
      ▶ 통신을 수행하는 프로세스는 서로 부모/자식 프로세스 관계여야한다.
      생산자 프로세스부모 프로세스로서 파이프 좌측종단( = write end )에 데이터를 생성
      소비자 프로세스자식 프로세스로서 파이프 우측종단( = read end )에서 데이터를 읽음

      Ordinary Pipe2개의 File Descriptor를 활용한 단방향 ( Unidirectional ) 통신을 수행
      양방향 통신 구현 시 2개의 Ordinary Pipe를 구현

      일반 파이프 구현 시 반드시 부모 / 자식 프로세스 관계로 정의하여 부모 프로세스에서는 Write End , 자식 프로세스에서는 Read End를 수행하며 두 프로세스 모두 Concurrently하게 실행하여 프로세스 간 통신을 구현
      파이프를 생성한 프로세스 이외는 접근 불가능

    • 지명 파이프( Named Pipe )
      프로세스 간 각 파이프에 이름을 지정
      양방향 통신 ( Bidirectional )
      부모 자식 프로세스Relationship이 없어도 사용 가능

UNIX SystemOrdinary Pipe 구현

Ordinary Pipe 생성 : pipe(int fd[])
입력종단 ( write end ) : fd[0]
쓰기종단 ( read end ) : fd[1]

부모 프로세스write end , 자식 프로세스read end를 수행하며 두 프로세스 모두 Concurrently하게 동시처리.

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 25
#define READ_END 0
#define WRITE_END 1
int main(){
  char write_msg[BUFFER_SIZE] = "Greetings";
  char read_msg[BUFFER_SIZE];
  int fd[2]; // file descriptor 초기화
  // 파이프 생성
  pipe(fd);
  // 자식 프로세스 생성
  pid_t pid;
  pid = fork();
  if (pid > 0){ // 부모프로세스
    // wait()이 없으므로 자식프로세스와 함께 실행
    close(fd[READ_END]);
    // 파이프 작성
    write(fd[WRITE_END], write_msg, strlen(write_msg)+1);
    close(fd[WRITE_END]);
  } else if ( pid == 0 ){ // 자식프로세스
    close(fd[WRITE_END]);
    // 파이프 읽기
    read(fd[READ_END], read_msg, BUFFER_SIZE);
    printf("read %s\n", read_msg);
    close(fd[READ_END]);
  }
  return 0;
}

  • 식별자 ( fd : file descriptor )
    파일 또는 I/O Resource를 처리하는 용도로 활용되는 Abstract Indicator

  • pipe(int배열)
    UNIX에서 IPC를 위해 Ordinary Pipe를 구현 시 사용하는 System Call
    WRITE or READ를 수행하는 2개의 식별자를 생성
int fd[2]; // file descriptor 초기화
  // 파이프 생성
  pipe(fd);

식별자 역할의 int fd[2]를 생성 및 매개변수로 전달시 Write EndRead End를 수행하는 2개의 식별자를 생성
Read End 용도 식별자 : fd[0]
Write End 용도 식별자 : fd[1]

  • File Descriptor 닫기
    。생성된 Ordinary Pipe단방향이므로 식별자write(fd) 또는 read(fd) 작업 후 특정방향으로 설정된 식별자를 닫는 과정이 필요.
    단방향이므로 각 용도의 실행중인 식별자를 종료해야 다른 용도의 식별자를 실행가능

    close(fd[0]) : Read End 용도 식별자 종료

    close(fd[1]) : Write End 용도 식별자 종료

  • 파이프에 메세지 작성
    write(fd[0], 메세지, 메세지크기)

  • 파이프에서 메세지 읽기
    read(fd[1], 버퍼, 버퍼크기)

네크워크상에서의 IPC System
Web Server 같은 Client - Server System에는 2가지 프로세스 간 통신방법이 존재 ( 소켓 , RPC )

  • 소켓 ( Sockets ) 컴퓨터네트워크 - 소켓

    네트워크 상에서 연결된 두 컴퓨터의 프로세스IPC를 위한 Endpoint
    IPC를 수행할 네트워크컴퓨터프로세스소켓번호로 식별

    Client SocketServer Socket으로 구분되어 소켓을 연결하여 두 프로세스 간 네트워크 통신을 가능하게함.

    프로토콜 계층 상에서 어플리케이션 계층프로세스트랜스포트 계층프로토콜Message를 전달하는 Interface 역할을 수행

    IPC 메카니즘으로 Message-Passing을 활용
    Pipes와 유사

    。네트워크 통신을 수행할 프로세스는 하나의 소켓을 가진다
    소켓을 생성하는 경우 Port Number가 식별자로서 각각의 소켓에 할당됨

    Socket = IP Address + Port
    IP Address 번호와 각 Host프로세스를 연결하는 파이프 용도의 Port의 번호를 조합하여 네트워크로 연결된 Host를 식별 후 IPC를 수행
    Pipe = Message Box = Port

    ex) www.google.com:8080의 경우 도메인 주소로 변환한 IP Addrss서버컴퓨터에서 Port를 통해 데이터를 요청
    도커 컨테이너에서 Port서비스의 단위로 해석할 수 있다
    ▶ 단일 IP Address를 가지면서 각각 다른 Port를 가지는 다수의 도커 컨테이너를 가질 수 있으므로
    • Server Socket
      Server Socket이 바인딩한 포트번호포트에 연결가능한 Client Socket수는 한정됨
      Load Balancing을 수행

    • Client Socket


  • 원격 프로시저 호출 ( RPC : Remote Procedure Calls )
    네트워크 상에서 연결된 컴퓨터의 프로세스Procedure Call 메카니즘을 추상화하여 설계된 IPC의 확장개념의 기술

    Client는 네트워크로 연결된 다른 컴퓨터를 Remote Host로서 Host프로세스의 함수 or 프로시저를 원격호출하여 지역함수처럼 실행

    SkeletonStub간 통신 시 데이터의 Marshaling을 수행하여 전송에 적절한 형식으로 변환

    Java에서는 RMI( Remote Method Invocation )로 구현됨
    • Stub( = Cilent Stub )
      Client Side에서 사용되는 Proxy 객체로서 Client가 다른 컴퓨터의 프로세스Remote Method를 호출하는 주체로 활용

    • Skeleton ( = Server Stub )
      Server-Side에서 실행되어 Stub을 통한 Client의 요청으로 Procedure Call한 실제 Method에 전달 및 결과를 Client에게 응답

Java에서의 Socket 구현
자바 Socket 관련 클래스
Java소켓네트워크 통신을 위한 API 역할을 수행

Socket 클래스와 ServerSocket 클래스의 객체를 생성하여 Server SocketClient Socket로서 활용

  • Server Socket
    Server-Side로서 TCP 서버 역할을 수행할 특정 포트번호로 바인딩된 ServerSocket Class의 객체 생성
    서버소켓객체는 바인딩된 포트번호Client Socket부터의 연결요청을 상시대기

    Client Socket로부터 연결이 된 경우 서버소켓객체.accept()를 통해 Client SocketSocket 객체를 반환
    Client SocketSocket Class객체가 반환된 경우 두 프로세스 간 연결이 정상적으로 되었으며 반환된 Socket 객체를 통해 통신을 수행

    。통신이 전부 수행된 경우 서버소켓객체.close() 를 통해 프로세스 간 연결종료
import java.io.*;
import java.net.*;
public class DateServer {
    public static void main(String[] args) throws Exception {
        // 포트 8080의 TCP 서버소켓 생성
        ServerSocket server = new ServerSocket(8080);
        while ( true ){
            // 포트:8080으로 Client Socket으로부터의 연결요청 대기
            System.out.println("연결대기중");
            // 연결요청 수신 및 Client Socket의 Socket 객체 반환
            Socket client = server.accept();
            PrintWriter pout = new PrintWriter(client.getOutputStream(),true);
            System.out.println("새로운 클라이언트 소켓 연결됨");
            pout.println(new java.util.Date().toString());
            // 소켓 종료 및 연결요청 재대기
            client.close();
        }
    }
}

.

  • Client Socket
    。연결을 수행할 특정 ServerSocket의 컴퓨터의 IP주소, 포트번호를 생성자로 전달하여 연결될 Client Socket 역할의 Socket 객체를 생성
    ▶ 해당 Socket 객체를 통해 데이터의 송수신을 수행
 import java.io.*;
import java.net.*;
public class DateClient {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 8080);
        InputStream in = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line = null;
        // 소켓으로부터 Date 를 Read
        while ((line = br.readLine()) != null ) System.out.println(line);
        // 소켓 연결 종료
        socket.close();
    }
}

출처
운영체제 공룡책 강의

profile
공부기록 블로그

0개의 댓글