소켓을 공부하면서 종료방법에 의문이 든다.
서버와 클라이언트가 메시지를 주고받을 때는 아래의 코드와 비슷하게 작성한다.
while((recv_len = read(clnt_sock, recv_msg, BUF_SIZE))!=0){
recv_msg[recv_len] = 0; // set last index '\0'
printf("[CLIENT] : %s\n", recv_msg);
}
위의 코드에서 read 함수로 읽어들인 데이터의 byte 수가 0이 아닐 경우에는 서버에 메시지를 출력하고 0일 경우에는 반복문을 나간다. 궁금했다.
첫번째, read 함수는 어떤 방식으로 읽을까?
분명히 while문을 계속 돌진 않을 것이다. 그래서 gdb를 통해 read 함수가 어떻게 작동하는지 확인해봤다.
위의 스크린샷에서 보면 read함수를 실행하면서 loop 에 들어간 것을 확인 할 수 있다. read함수는 클라이언트와의 통신소켓을 통해 세번째 인자 사이즈만큼 읽어들여 두번재 인자의 버퍼에 저장한다.
오케이, read 함수에서 클라이언트가 소켓을 통해 데이터를 쓰기 전까지 대기하고 있구나.
그럼 두번째,
클라이언트에서 종료하면 왜 0을 읽어서 while문에서 빠져나올까?
우선 recv_len 변수에 0이 저장되는지 확인해보자.
0이 저장되는 것을 볼 수 있다. 찾아보니 이렇게 설명되어 있다.
출력 스트림을 종료하면 상대 호스트로 EOF가 전송된다.
close() 함수는 입출력 스트림을 모두 종료하기 때문에 client가 close함수로 종료할 때 server에서는 EOF, 즉 0을 전송받고 while문을 나가게 된다. 이제 왜 while 문 조건에 0을 넣었는지 알 수 있게 되었다.
read 함수는 파일에 읽을 데이터가 없을 경우 0을 리턴한다고 한다.
read 함수의 시스템 콜은 파일의 끝(EOF)를 알려주기 위해 0을 반환하고 이는 에러로 처리되진 않는다고 한다.
아래 간단히 테스트를 해보았다. 데이터가 없는 파일을 만들고 이를 read 했을 경우 어떤 값이 반환되는지.. 역시나 0이다.
그렇다, 소켓도 파일이고 read함수 역시 파일 입출력의 함수이다. 그래서 0을 반환한거고.
'C' 카테고리의 다른 글
[Socket] thread (0) | 2022.06.28 |
---|---|
function pointer 함수 포인터 (0) | 2022.06.27 |
stack & heap in Visual Studio (0) | 2022.05.25 |
magic debug value (1) | 2022.05.25 |
stack using linked list (0) | 2022.05.14 |