[150906] 리눅스 C언어 소켓 프로그래밍
오늘 포스팅할 내용은 리눅스 환경에서의 C언어 소켓 프로그래밍이다. 네트워크 공부를 하면서 소켓 프로그래밍도 겸하면 좋겠다고 생각하고 있었는데, 어느 환경에서 해야 할지 고민이 많았다. 그런데 마침, 학교에서 강의도 진행하고 언어도 배우는 겸, 리눅스 (Xubuntu)에서 진행하기로 결정했다. 리눅스를 거의 사용해보지 않아서 터미널을 사용하는데 많이 애먹었다. 어쨌든, 기초부터 살펴봐야 하므로 인터넷을 통한 통신이 아닌, 같은 기기 내에서 다른 프로세스 끼리의 통신을 진행해보자.
아, 그리고 논외로.. 계속 포스팅하는 레이아웃이 왔다갔다하는데.. 어떤 방식으로 포스팅하는게 가독성이 좋을지 찾아보고 있는 중이다. 모르는 개념들을 구글링 하면서 찾는 중에 티스토리 레이아웃을 아주 깔끔하게 개인 홈페이지 마냥 꾸며놓으신 분들이 수두룩했다.. 티스토리 하려면 웹언어도 마스터해야하나 싶다.. 자, 이제 진짜 각설하고 본 내용에 들어가자.
....소켓이다. 말장난을 하려는게 아니라, 역시 비슷한 의미를 가지고 있기에 가져와봤다. 가장 크게 보면 서로 다른 호스트 간의 데이터 전송 및 통신을 위해 개발됐다고 한다. 일반적으로 서버와 호스트가 가동 중이라고 가정했을 때, 소켓 통신의 대략적인 흐름은 다음과 같다. (TCP 기준)
SERVER)
Socket 생성 -> Bind(소켓 주소 할당) -> Listen (클라이언트의 접속 대기) -> Accept (접속 허용) -> Read / Write (데이터 읽기 / 쓰기) -> Close (연결 종료)
CLIENT)
Socket 생성 -> Connect (Server의 Listen 모드와 연관) -> Read / Write (데이터 읽기 / 쓰기) -> Close (연결 종료)
자세하게 설명하자면,
1) 서버와 호스트는 각 각 자신에 대한 주소 정보(IP / PORT) 와 통신 방식 (TCP / UDP)을 담은 소켓을 생성한다.
2) 서버는 자신의 주소 정보를 Bind 하는데, 이는 어플리케이션으로 향하는 소켓 번호와 소켓 주소 를 연관시켜 주는 역할을 한다.
+ 소켓 번호는 어플리케이션이 알고 있는 통신용 통로 번호, 소켓 주소는 프로토콜(TCP/IP)가 알고 있는 주소라고 해석할 수 있는데, 이 둘을 묶어줘야 어플리케이션에서 네트워크로의 통신이 가능해지기 때문
+ 왜 클라이언트는 Bind 하지 않을까? 그 이유는 클라이언트는 자신 외에 다른 호스트들이 자신의 주소를 알 필요가 없기 때문이다. 서버의 경우 클라이언트의 목적지가 되기 때문에 주소 정보가 필요하지만, 클라이언트 자체는 오로지 서버를 목적으로 하기 때문에 Bind 할 필요가 없다.
3) 서버는 수동 대기모드 Listen 으로 클라이언트의 접속을 계속해서 기다린다. 이 때, 클라이언트로부터 접속이 감지되면 Accept를 호출한다.
4) 서버는 클라이언트의 접속을 허용하고 이 후 단계로 넘어간다. Read / Write 단계는 말 그대로 버퍼 등을 이용해서 데이터 전송을 하는 과정을 말한다.
5) 클라이언트는 원하는 때에 Close 하여 연결을 끊을 수 있다.
다음은 낯선 소켓 프로그래밍을 구글의 숲을 헤치며 엉망으로 만들어 본 소켓 통신 예제이다. 인터넷 통신이 필요한 것도 아니며, 단순히 프로세스 간의 통신을 하는 아주 간단한 프로그램이다. 그런데, 이것저것 줏어보고 가며 코딩을 했더니 상당히 지저분해 보인다.
서버에서 입력받은 텍스트를 버퍼에 저장해서 클라이언트로 송신하고, 이를 클라이언트에서 출력하는 프로그램....인데, 소스코드는 다음과 같다.
소켓 통신에서 중요시되는 부분만 강조했다. TCP 환경에서 소켓 통신이 어떻게 이루어지는지에 대한 이해가 중요할 것 같다. 각 함수들이 어떤 역할을 하고 왜 그런 역할을 하는지 이해가 되면 자연스럽게 코딩할 때 쓰게 되는 것 같다. 아무래도 오늘 가장 중요한 내용은 Bind 함수가 아닐까 싶다. 그리고 전체적인 연결의 흐름, 3-hand-shaking 이 발생하는 자세한 원리에 대해서도 조금이나마 도움이 됐다. 아, 그리고 아래 링크는 소켓과 관련하여 많은 도움을 받은 웹페이지이다. 각 함수들이 어떤 역할을 왜 그렇게 하는지 자세하게 기술했다.
http://jkkang.net/unix/netprg/chap2/net2_intro.html
'프로그래밍 > 코딩(C & SOCKET)' 카테고리의 다른 글
[180508] Fast Change Directory (0) | 2018.05.08 |
---|---|
[151101] Raw Socket (0) | 2015.11.01 |
[151025] 리눅스 디스크립터 (0) | 2015.10.25 |
[150909] 리눅스 기반 채팅 chat_sv.c - 1 (0) | 2015.09.09 |
[150903] C언어 포인터 기초 개념 (0) | 2015.09.05 |