1. Socket
소켓이란 애플리케이션 프로세스와 end to end 프로토콜 사이에 문이 되는 요소 입니다. (=인터페이스)
애플리케이션 데이터를 트랜스포트 레이어로 내려주는 문이 되는 것입니다. 애플리케이션 개발자가 네트워킹 지원하는 애플리케이션을 개발하려고 한다면 소켓을 통해 데이터를 어떻게 전달할지 구현할 줄 알아야 합니다. 트랜스포트 레이어로 내려주는 소켓을 활용하는 방법만 알면 원하는 리시버한테 데이터를 전송할 수 있게 되는 것입니다. 즉 소켓은 네트워크와 네트워크 사이의 인터페이스가 됩니다.
1-1. 네트워크하는 데 필요한 인자들
네트워크를 하는 모든 호스트 머신들은 IP주소를 갖게 됩니다. IP주소를 가지고 원하는 목적지까진 잘 전달될 수 있어요. 하지만 우리가 최종 목적지는 호스트가 아니라 호스트 내에서 돌아가는 프로세스입니다. 해당 프로세스는 포트번호로 구별할 수 있습니다.
즉, IP주소로 호스트를 찾아가고 호스트 정보를 맵핑하는 포트번호가 필요합니다.
때문에 각 호스트는 65,536개의 포트를 갖고, 이 중 어느 정도는 용도에 맞게 reserve가 되어 있습니다. 개인적으로 쓰고 싶다면, 이미 reserve된 포트를 피해서 써야합니다.
실제로 네트워크 중간중간에는 방화벽이 많이 설치되어 있는데요. 포트번호를 기준으로 패킷 필터링을 많이 합니다. 포트번호가 이상한 것들은 악의적인 트래픽으로 간주해 드랍시키는 경우가 많습니다. 실제 네트워킹 애플리케이션 만들어 테스킹할 때 포트번호를 잘못지정하면 firewall같은 데서 block될 수 있습니다.
2. Socket programming
소켓을 통해서 소통할 수 있는 클라이언트 서버 애플리케이션을 만드는 것을 말합니다. 클라이언트와 서버가 통신하기 위해서 소켓 API를 통해 통신해야 합니다. 소켓 API는 유닉스에서 처음 만들어졌습니다.
애플리케이션 레이어를 유저스페이스라 부릅니다. TCP, IP부분 OS에서 담당하는 부분을 커널 스페이스라고 부릅니다. 이더넷 부분은 하드웨어가 되는 겁니다.
2-1. server and client
클라이언트는 대화를 시작하고 서버는 클라이언트로부터 요청이 오기를 기다립니다.
클라이언트에서는 소켓을 만들고 연결을 요청하는것 데이터를 주고 받는 것 연결을 끊는 것을 구현해야하고,
서버에서는 소켓을 만들고 연결을 기다리는 것 연결이 왔을 때 accept 하고 데이터를 주고 받고, 연결을 끊는 것을 구현해야 합니다.
2-2. 구현 맛보기
1) create a tcp socket - server
ServerSocket servSock = new ServerSocket(servPort);
여기서 중요한 점은 포트번호를 개발자가 지정해줘야 한다는 것입니다.
2) Listen (wait) & Accept new connection - server
실제 구현에서는 리슨과 억셉이 동시에 일어납니다. API 단에서 동시에 돌아가게끔 되어 있기 떄문이에요.
계속 listen하고 있다가 요청이 들어오면 새로운 클라이언트 전용 소켓을 만들게 됩니다.
즉, 요청을 기다리는 소켓 1개, 새로운 클라이언트 전용 소켓 1개가 있는 셈입니다.
for (;;) {
Socket clntSock =
servSock.accept();
위에 accept 메소드의 반환 값은 클라이언트 소켓 입니다. 이 소켓을 통해 데이터를 주고 받게 됩니다.
클라이언트와 연결이 안될 때는 block된 상태로 기다리고 있다가 연결 요청되면 소켓을 리턴하는 겁니다.
3. Create a TCP socket & Connect server - client
Socket socket = new Socket(serverIP, servPort);
client에선 소켓을 만들기 위해 2개의 인자가 필요합니다.
내가 어느 서버에 붙을건지 서버 IP주소가 필요하고요.
서버에서 어떤 포트의 프로세스에 붙을 건지를 알려주는 서버 포트넘버가 필요합니다.
위의 socket api는 소켓을 만듬과 동시에 서버에게 연결 요청을하는 것까지 포함합니다.
4. connect accept - server
Socket clntSock = servSock.accept(); <- Accept! & server TCP creates new socket for the client
accept 완료 후 클라이언트 소켓이 만들어져 데이터를 주고 받는 겁니다.
InputStream in = clntSock.getInputStream();
클라이언트 소켓을 통해 inputStream 개체를 만들 수 있습니다.
recvMsgSize = in.read(byteBuffer);
위에서 얻은 in 스트림 매개체를 통해 read 매소드를 할 수 있습니다.
이는 자바에서 배운 파일 입출력과 유사합니다. 파일을 통해서 읽고 썼죠. 관점만 약간 바꾸면 네트워크 프로그래밍에서는 소켓을 통해서 입출력을 합니다.
여기서 중요한 점은 소켓 객체를 통해서 input 스트림 객체를 얻어낸다는 것입니다.
5. 받은 데이터를 출력합니다. - client
OutputStream out = socket.getOutputStream();
out.write(byteBuffer);
아웃풋 스트림의 경우도 소켓 객체를 통해 사용되고 있습니다.
6. 소켓을 닫습니다.
close(clntSocket) - server
close(sock); - client
2-3. 소켓 프로그래밍 요약
server
- 로컬 소켓을 만든다 (create)
- 특정 포트에 로컬 소켓을 바인드 시킨다. (binds)
create와 bind는 소켓을 생성시키면 한 번에 된다.
- 커넥션을 듣는다. (listens)
- 연결을 수락한다. (accepts)
이 둘도 구현에선 한 번에 구현됩니다.
그 후 입출력 시스템을 통해서 데이터를 주고 받게 됩니다.
client
개발자임으로 어느 서버와 포트에 붙는지 알아야 합니다.
- 서버와 포트를 가지고 소켓을 만듭니다.
- 소켓을 만들면서 remote 소켓에 연결합니다.
위에서 말했다시피 생성과 연결은 한 줄로 끝납니다.
그 후 데이터를 주고 받습니다.
서버가 여러 명의 클라이언트와 대화할 수 있도록 지원하게 됩니다.
'CS > 컴퓨터 네트워크' 카테고리의 다른 글
컴퓨터 네트워크 13일차 : TCP/IP, ACK time out 시퀀스넘버 (0) | 2021.10.13 |
---|---|
컴퓨터 네트워크 12일차 : 소켓프로그래밍 멀티쓰레드 (0) | 2021.10.12 |
컴퓨터 네트워크 11-1일차 : Pipelined protocol (GO-BACK-N / Selective Repeat) (0) | 2021.10.06 |
컴퓨터 네트워크 10일차 : transport layer rdt / 9일차 복습 (0) | 2021.10.03 |
컴퓨터 네트워크 9-2일차 : 신뢰 높은 데이터 전송, rdt 버전 (0) | 2021.09.29 |