code : LAZYIRC
co-work : with @sojoo @yachoi @hyunjcho
date : 2023/01 - 2023/02
컴퓨터 네트워크를 대상으로 하는 입출력 행위를 다루는 프로그래밍
socket : 전화기
전화기에 연결되는 번호 : 포트번호
전화기에 번호를 연결 : bind
각 전화기가 전화를 기다리는 상태 : listen
전화기에 전화가 오는 상태 : accept
수화기를 들어서 전화를 연결 : read
1.Socket
프로그램이 네트워크에서 데이터를 송수신할 수 있도록,
"네트워크 환경에 연결할 수 있게 만들어진 연결부"가 바로 네트워크 소켓(Socket)
네트워크에 연결하기 위한 소켓 또한 정해진 규약, 즉, 통신을 위한 프로토콜(Protocol)에 맞게 만들져야 함.
보통 OSI 7 Layer(Open System Interconnection 7 Layer)의 네 번째 계층인 TCP(Transport Control Protocol) 상에서 동작하는 소켓을 주로 사용하는데, "TCP 소켓" 또는 "TCP/IP 소켓"이라고 함. (UDP에서 동작하는 소켓은 "UDP 소켓")
2.CLIENT SOCKET & SERVER SOCKET
클라이언트 소켓(Client Socket)과 서버 소켓(Server Socket)의 역할.
데이터를 주고받기 위해서는 먼저 소켓의 연결 과정이 선행되어야 하고, 그 과정에서의 연결 요청과 수신이 각각 클라이언트 소켓과 서버 소켓의 역할.
마치 클라이언트 소켓(Client Socket)과 서버 소켓(Server Socket)이 태생적으로 구조가 다른, 전혀 별개의 소켓(Socket)인 것처럼 보일 수 있지만, 두 소켓(Socket)은 태생적으로 동일함. 소켓의 역할과 역할에 따라 처리되는 흐름, 즉, 호출되는 API 함수의 종류와 순서들이 달라서 다르게 부르는 것이고, 전혀 다른 형태의 소켓이 아님.
3.연결 순서
두 개의 시스템(또는 프로세스)이 소켓을 통해 네트워크 연결(Connection)을 만들기 위해서는, 최초 어느 한 곳에서 그 대상이 되는 곳으로 연결요청이 선행. IP 주소와 포트 번호로 식별되는 대상에게, 자신이 데이터 송수신을 위한 네트워크 연결을 수립할 의사가 있음을 알리는 것.
한 곳에서 연결 요청을 보낸다고 하더라도 그 대상 시스템이 그 요청을 받아들일 준비가 되어 있지 않다면, 해당 요청은 무시되고 연결은 만들어지지 않음.
4.클라이언트 소켓의 실행흐름
클라이언트 소켓(Client Socket)은 처음 소켓(Socket)을 1.생성(create)한 다음, 서버 측에 2.연결(connect)을 요청. 그리고 서버 소켓에서 연결이 받아들여지면 데이터를 3.송수신(send/recv)하고, 모든 처리가 완료되면 소켓(Socket)을 4.닫는다(close).
5.서버 소켓의 실행흐름
소켓(Socket)을 1.생성(create)하고 서버가 사용할 IP 주소와 포트 번호를 생성한 소켓에 2. 결합(bind). 그런 다음 클라이언트로부터 연결 요청이 수신되는지 3.주시(listen)하고, 요청이 수신되면 요청을 4.받아들여(accept) 데이터 통신을 위한 소켓을 생성. 일단 새로운 소켓을 통해 연결이 수립(ESTABLISHED)되면, 클라이언트와 마찬가지로 데이터를 5.송수신(send/recv)할 수 있습니다. 마지막으로 데이터 송수신이 완료되면, 소켓(Socket)을 6.닫는다(close).
6.서버소켓 프로그래밍
BIND
각 소켓은 시스템이 관리하는 포트번호들 중 하나의 포트 번호를 사용하게 되는데, 이 번호가 중복될 경우 어떤 포트로 수신된 데이터가 어떤 소켓을 위한건지 알수 없게됨. 소트가 중복된 포트 번호를 사용하지 않도록, 내부적으로 포트번호와 소켓연결 번호를 관리 -> 만약 다른 소켓이 해당 번호를 사용하고 있다면 에러를 리턴함. 일반적으로 서버소켓이 고정된 포트번호를 사용.
=> 이제 클라이언트의 연결요청을 수신할 준비가 됨.LISTEN
클라이언트의 연결요청이 수신되기를 기다리는 곳.
서버 소켓에 바인딩된 포트번호롤 클라이언트의 연결 요청이 있는지 확인하면서 대기상태에 머무름. 요청이 수신되면, 대기상태를 종료하고 리턴함.
listen이 대기상태에서 빠져나오는 경우는 2가지 1. 클라이언트의 요청이 수신된 경우, 2. 에러가 발생한 경우 (소켓이 close됨)
리턴되는 값으로 클라이언트 요청이 수신되었는지, error로 인한건지 확인 가능 (client에 대한 정보는 포함 x)ACCEPT
소켓 연결을 실질적으로 수행하는 절차.
데이터통신을 위해 연결되는 소켓이 bind, listen에서 쓰는 소켓이 아님에 주의해야함.
accept내부에서 연결을 위해서 새로 만들어지는 소켓에 연결됨.
동시에 여러개의 I/O를 대기할 경우에 특정한 fd에 blocking되지 않고 I/O를 할 수 있는 상태인 지를 모니터링하여 I/O 가능한 상태의 fd인지를 검사하는 함수. 대기하고싶은 특정fd에 대해서 저장하고있는 pollfd라는 구조를 인자로 넘긴다.
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
파일 컨트롤 함수로, 열려 있는 파일의 특성을 변경하기 위해 사용하는 함수.
F_SETFL : arg 에 지정된 값으로 파일지정자 fd 의 플래그를 재 설정한다. 리눅스에서 이 명령은 O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, O_NONBLOCK 플래그만 바꿀 수 있다.
O_NONBLOCK : read/ recieve시에 기다리지 않고 바로 리턴하게하는 플래그.
int fcntl(int fd, int cmd, int arg);