출처 : http://sthyun.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%ED%95%A8%EC%88%98%EC%9D%98-BlockingNon-Blocking-IO-%EB%8F%99%EC%9E%91

1. 입력함수: read, readv, recv, recvfrom, recvmsg

Blocking TCP 소켓인 경우, 소켓수신버퍼에 수신된 데이터가 없으면, 프로세스는 sleep한다. 데이터가 도착하면 (그것이 충분한 크기가 아닐지라도) 프로세스는 깨어난다. 원하는 크기만큼 도착할때까지 기다리려면, while로 계속 받아 붙이던가, 아니면, MSG_WAITALL 플래그를 이용한다.

UDP 소켓인 경우, 소켓수신버퍼가 비어 있으면, 프로세스는 sleep한다. UDP패킷이 도착하면, 프로세스는 깨어난다.

Nonblocking 소켓의 경우, 수신버퍼가 비어 있는 경우, 에러 EWOULDBLOCK 으로 바로 리턴한다.

 

2. 출력함수: write, writev, send, sendto, sendmsg

Blocking TCP 소켓의 경우, 출력함수는 어플리케이션의 데이터를 커널의 소켓전송버퍼에 복사한다. 만약 소켓전송버퍼에 공간이 없으면, 프로세스는 sleep한다.

Nonblocking TCP 소켓의 경우, 소켓전송버퍼에 공간이 없는 경우, 에러 EWOULDBLOCK으로 바로 리턴한다. 만약 소켓전송버퍼에 약간의 공간이 있는 경우, 복사가능한 공간을 바이트로 리턴한다.

UDP소켓은 실제로 소켓 전송 버퍼가 없다. 즉, 호출 즉시 UDP/IP스택으로 전달하므로, block되지 않는다.

 

3. accept 함수

Blocking 소켓인 경우, 새로운 연결이 없으면, 프로세스는 sleep한다.

Nonblocking 소켓의 경우, 새로운 연결이 없으면, 에러 EWOULDBLOCK으로 리턴한다.

 

4. connect 함수

Blocking TCP 소켓의 경우, 실제 연결이 될 때까지, 즉 SYN에 대한 ACK을 받을때까지 block되어 있는다.

NonBlocking TCP 소켓의 경우, 에러 EINPROGRESS로 리턴한다. (같은 호스트의 경우에는 바로 정상 연결이 이루어 질 수 있다)

UDP 소켓의 경우 connect는 가상의 연결을 만드는 것이라서 바로 리턴한다.

 

(참고: UNIX Network Programming, vol.1, 2nd edition, Ch.15)

 

5. close()

1. Connect 관련 Test

Ÿ 정상적인 경우의 Connect

내용

정상적으로 Connect가 이루어지는 경우, Connect 호출 후, 접속 완료까지 소요되는 시간

방법

Connect 호출 전, 호출 후의 시간을 측정하여 표시한다.

결과

호출 전 시간과 호출 호의 시간이 동일하게 표시됨

Window의 Timer의 유효치 이내의 시간으로 접속

결과분석

 

Ÿ Server Process가 없는 경우의 Connect

내용

연결할 IP에 대한 Computer가 켜져 있으나, Server Process가 없는 경우, Connect Fail의 형태

방법

Server Process를 실행하지 않고 Connect 시도

결과

1, 2초 후에 Connect Fail 발생

결과분석

연결할 Computer에서 Bind된 Port가 없음을 알 수 있으므로 Timeout은 발생하지 않고, 일정 시간내에 Connect Fail이 발생함

Ÿ 연결대상 Computer가 없는 경우의 Connect

내용

연결할 IP에 대한 Computer가 존재하지 않거나 꺼져 있는 경우, Connect Fail의 형태

방법

없는 IP에 대한 Connect 시도

결과

20여초 후에 Connect Fail 발생

결과분석

Timeout 될 때까지 IP를 찾음

 

2. Send/Receive 관련 Test

Ÿ Network Cable을 제거한 즉시 Send

내용

Network Cable을 제거한 즉시 Send를 하는 경우에 대한 결과

방법

Socket 연결 후, Network Cable을 제거한 즉시 Send 시킴

결과

Send가 성공함

 

[Non Blocking Mode]

Socket Close 메시지가 발생할 때까지 성공

[Blocking Mode]

Socket Close 메시지가 발생할 때까지 첫 Send는 성공, 두번째부터는 실패함

 

연결이 끊긴 것을 감지할 때까지는 성공함

7초 정도가 지난 후, 연결 끊김을 감지함

상대방의 Network Cable을 제거하였을 경우에는 약 3분 정도의 시간이 지난 후, 연결 끊김을 감지함

결과분석

Network Cable을 제거하더라도 한동안 Process는 그것을 인식하지 못함

Send는 TCP/IP 하부 레벨에 데이터 전송이 처리되면 성공으로 간주하는 것으로 판단됨

Ÿ Network Cable을 제거한 즉시 다시 연결 후 Send

내용

Network Cable을 제거한 즉시, 다시 Cable을 연결하여 Send 성공여부를 Test

Receive 측 Data Receive 성공여부도 함께 Test

방법

Network Cable을 제거 후, Close를 감지하기 전에 다시 연결하여 Send, Receive의 성공여부를 Test함

결과

Send, Receive 모두 성공

결과분석

Close를 감지하기 전에 다시 Cable을 연결하면, 연결은 유지됨

Ÿ Network Cable을 제거 후, 다시 연결하는 시간을 변화하여 Send

내용

Network Cable 제거 후, 다시 연결하는 시간을 변화시켜 위의 Test를 반복하여 성공여부를 확인

방법

Network Cable 제거 후, 다시 연결하는 시간을 변화시켜 위의 Test를 반복하여 성공여부를 확인

결과

Close를 감지하기 전에 다시 연결하면 Send, Receive 모두 성공

결과분석

 

Ÿ Send 후, Receive를 호출하지 않은 경우

내용

Data를 Send하고 Receive 측에서 Receive 함수를 호출하지 않는 경우, Timeout 발생여부와 Timeout 발생시간을 확인

방법

Data를 Send하고 Receive측에서 Receive 함수를 호출하지 않음

결과

Timeout이 발생하지 않음

결과분석

 

Ÿ Send, Receive Message 발생 수 소규모 데이터

내용

비교적 작은 크기의 데이터(수십 byte 내외)를 아주 빠르게 Send를 여러 번 호출하는 경우, Receive 측에 Receive Message의 발생과 실제 Receive한 Data의 크기를 확인

- Send 수와 Receive Message 발생 수를 비교검사

- Send한 Data 크기와 Receive한 Data 크기 비교

- Receive 시에 실제 Send한 Data보다 수배의 크기의 Buffer로 Receive한 경우와 Send한 Data의 크기와 동일한 크기의 Buffer로 Receive하는 경우의 비교

방법

100 Byte 크기의 Data를 10번 Send함

결과

Ÿ Receive Buffer 크기가 1024 byte인 경우

-       Receive Message 2번 발생

-       첫번째는 100 byte를, 두번째는 900 byte를 Receive 함

Ÿ Receive Buffer 크기가 100 byte인 경우

-       Receive Message는 10번 발생

-       모두 100 byte 씩 Receive함

결과분석

작은 크기의 데이터를 빠르게 연속적으로 전송하는 경우, Network 하부 Layer에서 몇 개의 데이터를 묶어서 한꺼번에 전송하게 된다. 따라서 Send한 Data와 실제 전송되는 Data 크기는 달라질 수 있으며, Send한 수와 Receive Message의 발생 또한 다를 가능성이 있다.

하지만 두번째 Test 결과로 봤을 때, Socket의 내부적인 Buffer에서 Receive Buffer로 Data를 읽어 들일 때, 내부 Buffer를 모두 비울때까지 Receive Message를 자체적으로 발생시키는 것으로 예상된다.

Ÿ Send, Receive Message 발생 수 대규모 데이터

내용

비교적 큰 크기의 데이터(수십 Kbyte 이상)를 Send 하는 경우, Receive 측에 Receive Message의 발생과 실제 Receive한 Data의 크기를 확인

방법

다양한 크기의 Data를 10번 Send 함

결과

- 50Kbyte 크기의 Data일 경우, Receive Message 33번 발생. 한번에 약 1.7Kbyte 수신

- 10Kbyte 크기의 Data일 경우, Receive Message 14번 발생. 한번에 받는 양이 일정하지 않음

- 100Kbyte 크기의 Data일 경우, Receive Message 63번 발생. 한번에 약 17Kbyte 수신

결과분석

한번에 큰 크기의 데이터를 Send하는 경우, Receive 측에서 Receive Message가 발생한 시점에 모든 데이터가 전송되지 않는다. 따라서 Receive Message 발생 시점에 Receive 함수를 호출하면 호출 시점까지 전송된 데이터만을 읽어들이게 된다. 그 이후 전송되는 데이터들은 별도의 Message가 다시 발생하며, 모든 데이터가 Receive될 때까지 Receive Message가 발생한다.

따라서 대용량 Data를 Receive하는 경우에는 데이터의 길이에 대한 정보를 미리 받아서 그 데이터가 모두 도착할때까지 읽도록 하여야 완전한 데이터를 수신할 수 있다.

Receive Message의 발생은 Receive Buffer의 크기와 한번의 Receive Message에 대해서 호출되는 Receive 함수의 수에 따라 그 발생횟수는 달라질 수 있다.

 


3. Close 관련 Test

Ÿ Close Message 발생 Test

내용

각 상황에 따른 Close Message의 발생여부 검사

-       Process를 비정상적으로 강제 Kill 시킨 경우

-       Computer의 전원이 꺼진 경우

-       Network Cable을 제거한 경우

-       Network Cable을 제거한 후 다시 연결하고 접속을 해제하는 경우

-       Network Cable을 제거한 후 Prcess를 종료하고 다시 Cable을 연결하는 경우

방법

 

결과

-       작업관리자에서 Process를 종료하였을 경우 Close Message 발생함

-       Network Cable을 제거한 경우 자신의 Cable 제거시 7초정도, 상대방 Cable 제거시 3분 정도 후에 Cloase Message 발생

-       Network Cable 제거 후 Close Message가 발생하기 전에 다시 연결하여 접속을 해제하는 경우, 정상적으로 Close Message 발생

-       Network Cable을 제거한 후 Process를 종료하고 다시 Cable을 연결하는 경우, Close Message 발생하지 않음

결과분석

 

 



+ Recent posts