반응형


- 본 내용은 Linux (Ubuntu 14.04 lts)를 기반으로 제작되었습니다. -


소캣 프로그래밍은 TCP/IP 기반으로 하였습니다.







지금까지 TCP/IP에 대한 내용, fork() 함수 이용 방법의 토대로 


TCP/IP에서 하나의 서버에 다중 클라이언트가 접속하는 법을 프로그래밍 해본다.



결론적으로, 구조는 다음과 같이 설계한다.


 

지금까지 배운 TCP/IP 구조에서는 하나의 서버에 다수의 클라이언트가 진입할 수 없는 구조이며,


하나의 Server와 Client가 통신하는 방법이기에 


아래의 그림에서는 3개의 Client중 1개의 Client만이 Server와 통신 할 수 있다.



그래서 서버는 fork()를 시켜 여러개의 서버를 만들고 


Client하나당 Server하나를 제공해야 되는 방식을 이용해야 한다.



서버의 구조를 자세히 보면, 이렇게 listen함수와 accept함수가 존재하는데


listen함수와 accept함수에 대해 다시 되짚어 보면,


listen함수는 연결 대기 상태로의 진입을 위한 함수이다. 


클라이언트에서 연결 요청 시 소켓이 하나 존재하여아 하는데, 이때 listen 함수가 호출되면, 서버 소켓이 만들어지고


두 번째로 인자로 전달되는 정수의 크기에 해당되는(여기서는 LISTEN_QUEUE_SIZE를 의미) 대기실이 만들어진다.


이것을 '연결 요청 대기 큐'라고 한다.


이후 listen 함수 호출 이후 클라이언트의 연결 요청이 들어왔다면, 들어온 순서대로 수락을 해줘야 하는데,


이때 위에서 만들어진 서버 소켓은 이미 요청을 받는 용도로 이용되고 있으므로 소켓을 하나 더 만들어야한다.


이것을 위한 함수가 accept함수이다. 




이렇게 listen소켓과 connect소켓은 listen에 이용되고, accept에서 이용된다.


즉, Listening Socket은 계속해서 클라이언트의 연결 요청을 들어오고,


Connecting Socket은 그 연결 요청에 대해 연결을 해주는 역할이다.


그렇다면 클라이언트와 서버간의 관계는 아래와 같은 형식으로 이루어 질 수 있는데,


이것을 어떻게 구현하냐가 문제가 되는것이다.








아래 그림을 보면, 부모 서버에서 fork()된 자식 서버에는 LS가 없다. 그리고 부모 서버에는 CS가없다.


즉, 부모 서버는 연결 요청에 대해 듣기만 해주고, 자식 서버에서는 그 연결 요청에 대해 수용만 해주는 역할을 한다.


이렇게 하면 부모 서버에서는 듣기만, 자식 서버에서는 클라이언트와 연결만 하게 된다.


클라이언트는 1번을 통해 연결 요청을 하고 2번을 통해 부모 서버는 자식 서버를 fork()한 뒤, 어셉트를 하도록한다.


마지막으로 3번 처럼 클라이언트와 자식 서버가 연결이 된다.





결론적으로 다음과 같이 TCP/IP에서의 서버와 다중 클라이언트의 통신이 가능하게 된다.




이 과정에 대한 소스 코드는 그 다음 게시물에서 확인 할 수 있다.

반응형