프로세스는 Shared memory 와 message passing 방법을 이용해서 서로 통신할 수 있다. (IPC) 이 방법들은 client-server 시스템에서의 통신 수단으로 활용될 수 있다.
이 외에 client-server 시스템에서 활용하는 세 가지 방법에 대해서 알아보자 : socket, remote procedure calls(RPCs), pipes.
Sockets
소켓은 통신을 위한 종단점이다. (A socket is defined as an endpoint for communication) 프로세스의 쌍이 네트워크 상에서 통신하려면 프로세스당 하나의 소켓을 갖고 있어야 한다.
소켓은 IP 주소와 port 번호를 이은 것으로 식별된다. 서버는 특정한 포트에서 클라이언트의 요청이 들어오는지를 들으며 기다린다. 요청이 receive 되면 서버는 클라리언트 소켓으로부터 온 연결을 accept 함으로써 연결을 완성한다.
Port Number?
특정한 서비스들을 구현하는 서버들은 (예를 들어 텔넷, FTP, HTTP 등) 정해진 포트 넘버가 있다. 텔넷은 port 23, FTP는 port 21, 그리고 HTTP 혹은 Web 은 port 80번을 듣는다. 1024번 밑의 포트 번호는 "널리 알려져 있다"라고 약속하며, 우리는 이 번호들을 이용해 표준화된 서비스들을 개발할 수 있다.
클라이언트 프로세스가 연결을 위한 요청을 시작하면 자신의 host computer 에 의해서 port 번호가 할당된다. 이 port 는 1024 이상의 작위적인 번호이다. 예를 들어 host X 에 있는 클라이언트의 IP 주소가 146.86.5.20 이고, 웹 서버 (port 80) 와 연결을 하고 싶으면 host X 에는 임의의 포트 넘버(1625와 같이)가 할당된다. 이 연결은 한 쌍의 소켓으로 이루어지고 각 소켓의 식별자는 `클라이언트IP주소:1625`와 `서버의IP주소:80` 가 된다. 모든 연결은 고유해야 하므올, host X 상의 다른 프로세스가 서버와 연결을 하려면 다른 port 번호를 갖는다.
Java 에서의 소켓
자바에서 소켓은 세 종류가 있다.
1. Connection-oriented (TCP) socket => Socket class
2. Connectionless (UDP) sockets => DatagramSocket class
3. MulticastSocekt class 는 DatagramSocket 의 하위클래스. 데이터를 여러개의 수신자에게 보낼 수 있도록 한다.
예시 코드 (Server)
import java.net.*;
import java.io.*;
public class DateServer{
public static void main(String [] args){
try{
ServerSocket sock = new ServerSocket(6013);
while(true){
//연결을 듣는다
Socket client = sock.accept();
PrintWriter pout = new PrintWriter(
client.getOutputStream(), true
);
//소켓에 데이터를 적는다
pout.println(new java.util.Date().toString);
//소켓을 닫고 다시 연결을 듣는 과정을 반복한다
client.close();
}
}
catch(IOEXception e){
System.err.println(e);
}
}
}
예시에서는 TCP 소켓을 사용해 Date Server 를 만들었다. 클라이언트는 서버에 현재의 날짜와 시간을 요청하고 응답을 받을 수 있다. 서버는 6013번 포트를 듣고 있고, 클라이언트가 연결이 되면 데이터를 전달해준다.
위의 코드에서 accept() 함수를 호출하면 코드가 block 되고 클라이언트의 연결 요청을 계속해서 기다린다. 연결이 되면 accept() 는 클라이언트와 소통할 수 있는 소켓을 반환한다.
예시코드 (클라이언트)
import java.net.*;
import java.io.*;
public class DateClient{
public static void main(String [] args){
try{
//서버 소켓에 연결한다
Socket sock = new Socket("127.0.0.1", 6013);
InputStream in = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
//소켓에서 날짜를 읽는다.
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
//소켓을 닫는다
sock.close();
}
catch(IOException e){
System.err.println(e);
}
}
}
127.0.0.1 은 loopback 이라 알려진 특별한 IP주소이다. 컴퓨터가 해당 주소를 참조하면 이것은 자기 자신을 참조하는 것이다. 이 메커니즘은 같은 호스트 상의 클라이언트와 서버가 TCP/IP 프로토콜을 이용해 통신하는 것을 가능케 한다.
소켓을 이용해서 통신하는 것은 흔하고 효율적이지만 매우 low-level 형태의 통신 방법이다. 왜냐하면 소켓을 통해서 통신할때는 구조화되지 않은 바이트의 스트림들만이 교환될 수 있기 때문이다. 따라서 클라이언트 혹은 서버 어플리케이션이 데이터를 구조화하는 작업을 해주어야 한다.
'Operating System' 카테고리의 다른 글
[System Software] C언어&어셈블리 예제 (0) | 2021.02.07 |
---|---|
[System Software] 논리연산 & Data Transfer 연산 / Branch & Jump 연산 (0) | 2021.02.07 |
[System Software] MIPS Operators (0) | 2021.01.26 |
[System Software] ISA / MIPS (0) | 2021.01.24 |
[OS] Process : A Program in Execution (0) | 2020.06.27 |