[네트워크] 클라이언트의 시스템콜(connect)

minji·2021년 10월 27일
0
post-custom-banner

서버에서는 socket() 함수로 소켓 디스크립터를 할당받은 후,
bind() -> listen() -> accept() 시스템콜을 차례로 호출해 클라이언트와 연결을 맺을 수 있음을 확인했다.

반대로, 클라이언트에서는 대기중인 서버에 연결 요청을 함으로써 서버-클라이언트 간의 연결이 생성될 수 있는데 이에 사용되는 시스템콜이 connect() 시스템콜이다.

1. 클라이언트의 소켓 생성 및 주소할당

클라이언트의 경우도 마찬가지로, 서버와 소켓 통신을 하려면 소켓을 하나 생성해야 한다.socket() 함수를 통해, 정수 sock에 디스크립터 번호를 저장한다.

cf) socket 함수가 -1을 리턴하는 경우?

socket() 함수는 첫 번째 인자인 프로토콜 타입과 두 번째 인자인 데이터 전송방식의 조합이 유효하지 않은 경우 에러(-1)을 반환한다.

socket 을 생성했으니, 다음으로 연결을 요청할 서버의 주소를 소켓에 할당한다.

이 때, 서버와 달리 클라이언트는 본인의 IP주소와 PORT번호를 따로 지정할 필요가 없는데, 이는 연결을 요청하는 시점에 커널이 알아서 모두 지정해주기 때문이다.
serv_addr 구조체에 서버의 IP주소, PORT번호, 프로토콜을 정의한다. 예제의 경우 IP 주소와 PORT 번호를 모두 사용자에게 입력받기 때문에 위와 같이 argv변수에서 가져오도록 작성했다.

2. 클라이언트의 연결 요청

이제 어느 서버에 연결을 요청할지 모두 결정했으니, 실제로 connect() 함수를 이용해 연결을 요청한다.
connect 함수 원형 (참조 : https://man7.org/linux/man-pages/man2/connect.2.html)

-sockfd : socket의 디스크립터 번호
-*addr : 연결을 요청할 서버의 구조체 주소
-addrlen : 서버 구조체 주소 변수의 길이

이렇게 클라이언트에서 connect() 시스템 콜을 호출하면 listen() 혹은 accept() 로 대기중이던 서버에 연결이 요청되며, 서버는 accept() 함수를 정상 리턴함으로써 두 호스트간 연결이 성립된다.

즉, connect 부터 accept 까지가 우리가 말하는 TCP 에서의 3-way-handshaking 과정이라고 할 수 있다.

profile
SW Engineer
post-custom-banner

0개의 댓글