Network/Network

이석복 네트워크 (3-1)socket&os, connection

finepiz 2022. 7. 27. 21:15

===

http://ocw.hanyang.ac.kr/?course=8477 

 

컴퓨터네트워크_3회차

애플리케이션계층1 (Application Layer) 사용자계층 네트워크애플리케이션종류 (Application layer protocols)

ocw.hanyang.ac.kr

 

===

소켓은 OS에서 제공하는 API의 일종, 다양한 펑션들이 있다

 

===

결국은 애플리케이션 프로세스(클라이언트 프로세스, 서버 프로세스)끼리의 통신이다

 

사용자 입장에서 애플리케이션 프로세스거나, 개발자 입장에서 애플리케이션 프로그램

우리가 OS내부 구현을 건드리는 건 아니야(다음 수업엔 그 내부를 들어가봄)

 

OS내부를 모르고 제공하는 서비스만 사용할 뿐. 그 서비스를 사용하기 위해 OS가 제공하는 특수한 인터페이스가 있다.

 

모니터창에 디스플레이하고 싶으면

printf()라는 애플리케이션 인터페이스를 사용해서 메시지를 적어주면

디스플레이되는것처럼

 

마찬가지로 네트워크 관점에서 다른 컴퓨터의 프로세스에 정보를 보이고 싶으면 그것에 맞는 인터페이스에 메시지를 적어주면 가는 것.

 

OS가 제공하는 API의 일종이다. 프로세스와 프로세스간의 통신을 위한 API를 소켓이라고 부르는 것

 

===

OS안에는 애플리케이션 레이어 밑에 있는 계층들이 구현돼 있다

트랜스포트레이어

네트워크레이어

..

 

애플리케이션 레이어와

OS간의(아래 계층) 인터페이스이기 때문에 (▽소켓이? api가 application programming interface)

 

바로 밑이 트랜스포트레이어가 있어서 결국 트랜스포트레이어가 제공해주는 걸 사용할 수 밖에 없어

 

현재 OS에는 트랜스포트레이어가 두가지 프로토콜이 구현돼 있어 TCP / UDP

 

그래서 애플리케이션 프로세스는 어쩔 수 없이 소켓을 사용하되 

TCP 소켓 / UDP 소켓 

둘 중에 하나만 고를 수 있어 두개밖에 없으니까

 

===

TCP통신을 사용하고싶다면 내가 TCP소켓을 만들어서 사용해야되고

UDP를 사용하고싶다면 UDP와 연결된 소켓을 사용해서 뭔가 데이터를 보내면 UDP방식으로 가는

 

소켓을 사용할 때 소켓의 종류 자체가 틀린 것

TCP소켓 인터페이스에다 데이터를 write하면 TCP방식으로 가는 것

UDP소켓 인터페이스에다 적으면 UDP방식으로 간다

 

===

TCP소켓은 SOCK_STREAM이라고 불린다

UDP소켓은 SOCK_DGRAM 소켓 데이터 그램이라고 불린다

 

===

소켓 관련된 펑션, API들

 

===

웹클라이언트와 웹서버의 통신

(뒤에 코드로 자세하게 보여준다)

socket() :먼저 웹 서버가 소켓을 생성

bind() : 방금 생성한 소켓을 특정 포트에다 바인드, 보통 웹서버는 80번이니까 80번에 바인드 같이

listen() : 나 이 소켓을 리슨 용도로 쓰겠다, 서버니까 듣고 있다

accept() : 난 클라이언트로부터 요청을 받을 준비가 됐어 들어와라

 

여기까지 수행되면 서버는 멈춘다, blocks. 클라이언트로부터 커넥션이 들어올 때까지

서버는 수동적으로 계속 가만히 있는다

 

그러다 어떤 클라이언트가 웹브라우저에서 동작을 취한다

socket() : 소켓을 열고

바로 connect() : 내가 원하는 어떤 서버의 프로세스한테 커넥트 하겠다.

둘 사이의 어떤 액션이 취해짐. 서버의 accept()가 클라이언트의 connect()가 불리면 진행이 되는 것

 

이 과정이 끝나면 TCP소켓 둘 사이의 단단한 연결고리가 형성

 

관계를 맺고 나면 간단히 write&read다. write()하면 저기서 read()할 수 있다

 

printf()로 메시지쓰면 생각없이 모니터에 디스플레이 되듯이

이 소켓에 메시지를 쓰면 저기에 튀어나옴. 전세계에 수많은 소켓중에 관계 맺은 저 소켓한테 뿅 튀어나옴

 

이게 통신

 

===

계속 뭔가 진행하다가 할말이 끝났으면 close()하고 끝낸다

 

===

API를 큰 그림으로 봤고, 좀 자세히 얘기해보면

소켓을 생성하는 소켓이라는 함수가 있고, 파라미터 3개

특정 포트에 매칭시키는 bind(), 파라미터 3개, 첫번째 파라미터가 방금 생성한 소켓의 인덱스

 

===

socker()

 

첫번째건 컨벤션 어쩌구..

 

진짜 중요한건 두번째 파라미터. 얘가 어떤 소켓을 생성할지 결정한다 TCP/UDP

TCP는 SOCK_STREAM 적어주면된다

 

소켓이 생성되면 소켓이라는 어떤 자료구조가 준비가 될거고

펑션의 리턴값으로 생성한 소켓의 인덱스(=파일디스크립터라고 불리는 소켓의 아이디) 리턴

이 id값으로 계속 이 소켓을 지칭한다

 

===

bind : 방금 생성한 그 소켓의 id를 사용해서 이 소켓을 특정 포트에 bind하겠다

 

===

listen : 방금 생성한 이 소켓을 listen용도로 사용할것이며

혹시라도 동시에 request가 동시에 들어올 경우 최대 n개까지 큐에 담아놓고 순서대로 처리하겠다

 

===

accpet : 준비 동작이 끝났으니 기다리겠다

실행되면 block하고있다가 커넥션 요청이 들어오면 수행이 되면서 리턴이 됨. 그러고 진행

리턴이 될 때 두번째 파라미터 안에 클라이언트의 IP와 포트넘버가 저장이 된다!

서버도 클라이언트의 포트넘버, 주소를 알게됨

 

===

다시 정리

서버에서 TCP소켓 만들고

bind 포트bind

listen용도로 지정

accept 기다리겠다

 

클라이언트 socket만들고

connect, 파라미터로는 당연히 서버의 주소겠지

*클라이언트는 남아도는 아무 포트나 쓰면 되니까 특정 포트에 bind할 필요가 없다

커넥션 완성

 

===

서버 샘플코드 보기

BACKLOG는 최대 10개 처리

제일 처음에 등장하는 API socker()

TCP소켓이다

성공적으로 생성이되면 음수값이 아니라 소켓 파일디스크립터(소켓아이디)가 나올 것

sockfd갖고 앞으로 지칭할 것

 

===

bind

방금 생성한 소켓을 특정 포트와 내 IP에다가 매핑시킨다

my_addr이 저 위에 main()에서 선언한 sockaddr_in이라는 스트럭쳐, 자료구조, 구조체인데 이게 저렇게 생겼다

여기다 정보를 다 집어넣어준다, port등

 

===

listen, accept

listen : 최대 10개(아까)

accept : 두번째거가 클라이언트 어드레스가 저장된

계속 실행되다가,

딱 여기서 멈춘대, 클라이언트에서 커넥션 요청 들어올 때까지

요청들어오면 실행되면서 두번째 파라미터에 클라이언트 정보가 들어온다

 

===

클라이언트 쪽

소켓 생성

TCP인지

sockfd이용해서 지칭

 

바로 connect

서버의 어떤 프로세스와 내가 connect를 할거다, 두번째에 서버의 주소

 

그다음 read&write 쭉

 

===

소켓id

쓰고자하는 메세지쓰고 수행이 되면 저쪽에서 read

 

===

 

===

UDP소켓

소켓 생성하고

커넥션 개념없이 바로 보내는 것

 

===

데이터 교환이 끝난 후 close사용해서 방금까지 사용했던 소켓을 release. 해제 시켜줘야 다른 프로세스가 쓸 수 있다

 

===

팁)

 

여러분이 프로젝트할 때

 

소켓을 생성하고 7777번 포트에 바인드하고, 뭔가 잘 안돼서 컨트롤 C를 누르면

프로세스 자체는 죽는데 프로세스에서 바인드한 포트 7777번은 한동안 release되지 않고 들고 있다

똑같은 포트를 쓰려고 하면 문제가 생긴다

컨트롤+C를 누를 때를 대비해서

이런 시그널 관련된 시스템 콜들을 코드에 적어주면 컨트롤+C눌렀을 때 관련된 소켓 자료구조들이 release된다

 

===

▽c로 웹서버 구현하는 프로젝트를 내시네

 

웹 브라우저창에다 뭘 치면 웹브라우저가 알아서 HTTP request를 만들어서 서버에게 보낸다

웹브라우저 역시 애플리케이션 프로세스라서 TCP소켓을 열어서 메시지를 보낸 것

우리가 만들 웹서버도 역시 TCP소켓을 열어서 데이터를 주고 받을 것

 

그럼 웹서버와 웹브라우저 사이에 꽉 물린 소켓이 있는 것

웹브라우저가 생성한 HTTP request는 소켓을 타고 서버소켓을 통해 들어와

서버에서 read()를 하면 HTTP request가 읽히고  ▽읽어야 읽히나봐

HTTP request를 화면에 띄우는것이 과제

get 어쩌구 나올 것

 

HTTP request왔으니까

어떤 파일 요청하는지 파싱해서 그 파일을 디렉토리에서 읽어서 HTTP response메시지를 작성해서 파일을 담아서 보내주는 것

▽서버에서 저런 일을 하는구나

 

컴퓨터 하나에서 웹서버 프로세스 만들어서 브라우저로 확인하면 된다

그럼 웹브라우저 창에다가 localhost:웹서버포트/index.html 이렇게 치면 request가 가겠지

실제로 IP찾아서 치든가

 

===

예)

프로세스의 실행파일이 myserver, 파라미터로 7777이 들어가면 bind에서 쓰인다

이 상태가 소켓 만들고 bind 7777, listen, accept, 기다리고 있는 상황. block된 상태.

저 프로그램 (코드길이) 얼마 안되고 방금 봤던 소켓 펑션들의 연속이다

이렇게 요청할 것

요청하면

위에것만 보기

프로그램이 메시지를 display시켰다

웹서버 프로세스에서 파일을 내 디렉토리에서 읽어서 HTTP response 메시지를 만들어서 write시켰더니

웹브라우저로 가서 그림이 나왔다

.txt

.jpg

.html

.mp3

를 다 지원할 수 있게(과제 요구사항)

 

192.168.1.183.7777/ 이렇게 오면 index.html갖다주면 되는데, 이 파일 안에 하이퍼텍스트 레퍼런스 .jpg ...많을 것

그런애들을 웹브라우저가 파싱해서 이것도 요청하고 저것도 요청하고

이렇게 일일이 나옴