2016-09-08 9 views
0

edge-triggered 모드에서 epoll을 사용하고 비 블로킹 소켓 작업을 수행하는 TCP/IP 서버 애플리케이션을 구현 중입니다. 클라이언트는 epoll없이 간단한 차단 작업을 사용하고 있습니다.C 소켓 원자 비 차단 읽기

"원자 읽기"를 서버 측에서 구현하는 방법을 알지 못합니다. "원자 읽기"에 대한 의미를 설명하려면 간단한 차단 작업이있는이 예제를 참조하십시오.

  • 클라이언트와 서버 모두 64K 버퍼를 사용하고 있습니다. (응용 프로그램 수준에서는 커널 수준의 소켓 버퍼를 변경하지 않습니다.)
  • 클라이언트는 단일 쓰기 작업으로 12K 데이터를 씁니다.
  • 서버에서 읽습니다. 이 경우 버퍼가 동일 할 때 항상 전체 12K를 읽습니다. 그래서 그것의 절반 만 읽을 수는 없습니다. 이것이 제가 "원자"라고 부르는 것입니다.

하지만 epoll 파일의 경우는 + 비 차단이 일어날 수있는 작업 :

  • 클라이언트와 서버 모두 64 개 K 버퍼를 사용하고 있습니다. (응용 프로그램 수준에서는 커널 수준의 소켓 버퍼를 변경하지 않습니다.)
  • 클라이언트는 단일 쓰기 작업으로 12K 데이터를 씁니다.
  • 6K는
  • 는 epoll 데이터가 응용 프로그램이 비 블로킹 작업을 사용하여 버퍼에 6K를 읽어 소켓
  • 에 도착 응용 프로그램을 알려주는 서버에 도착한다.
  • 읽기를 반복하면 EAGAIN/EWOULDBLOCK을 반환합니다.

이 경우 읽기는 "원자 적"이 아닙니다. 데이터가 단일 쓰기 작업으로 작성된 경우 읽기가 전체를 한 조각으로 반환한다는 보장은 없습니다.

데이터가 부분적 일 때를 알 수 있습니까? 한 가지 해결책은 데이터 크기를 항상 처음에 추가하는 것입니다. 그렇지 않으면 항상 연결을 닫고 다시 열 수 있지만 이러한 작업을 수행하지 않으려는 것입니다. 커널이 전체 블로킹 작업에 원 자성을 보장하기 때문에 "패키지"(BTW라고하는 단위는 어떻게됩니까?)가 도착했습니다.

감사합니다.

+3

당신은 일반적으로 * 루프 *의 모든 I/O를 작성하고 자신의 버퍼를 유지해야합니다. –

+0

소켓에서'read' 호출이'0'을 리턴하지 않았다면 이벤트 루프에서 캡처 할 수있는 더 많은 데이터가있을 것으로 기대할 수 있습니다. – jacob

+0

바이너리 전송에서는 전송 시작 ​​및 전송 종료와 같은 구분 기호를 추가하는 것이 일반적입니다. 텍스트 전송에서 구문 검사는 당신의 친구입니다. json 문자열을 전송하는 경우 json 문자열을 구문 분석하여 완료되었는지 여부를 확인할 수 있습니다. – alvits

답변

1

TCP는 스트림 기반이며 메시지 지향이 아닙니다. 블로킹 소켓의 경우에도 응용 프로그램이 보내는 정보가 한 번에 유선 상태로 유지된다는 것을 보장 할 수 없습니다. TCP는 자체 코스를 결정합니다.

그래서 원한다면 "원자 적"읽기를 수행하는 것은 응용 프로그램에 달려 있습니다. 예를 들면 다음과 같습니다.

응용 프로그램 프로토콜은 메시지 앞에 길이 바이트를 붙이도록 지시해야합니다. length 바이트는 해당 응용 프로그램 데이터의 크기를 피어에 알립니다. 물론 응용 프로그램은 2 바이트 길이 표시기가 시작될 때를 알고 있어야합니다.

[2 바이트 길이 MSG 이러한 정보 조치를 취해야 판독하고 프로그램에 기초하여 관심있는 데이터 바이트]

.msg length 바이트로 표시된 모든 바이트를 수신 할 때까지 소켓을 폴링해야합니다. 그런 다음에 만 데이터를 처리하십시오.

"원자 적"읽기가 필요하고 부분 읽기가 필요하지 않은 경우 recv에 MSG_PEEK 플래그를 사용할 수 있습니다. 소켓 버퍼에서 데이터를 제거해서는 안됩니다. 응용 프로그램이 소켓을 들여다보고 반환 값에 따라 필요한 수의 데이터가 소켓 버퍼에 있는지 확인하십시오.

ret = recv(sd, buf, MAX_CALL_DATA_SIZE, MSG_PEEK);

+0

나는 그것을 받아 들일 것이지만 그것을위한 업장이 없다;) 당신은 이것을 덧붙일 수는 있지만 "블록킹 케이스에 대한 당신의 추정은 정확하지 않다. 예를 들어, 서버는 읽기를 차단 한 상태에서 4K 만 읽을 수 있고 다시 돌아올 수있다." –

+0

NP! 더 많은 평판을 얻으려면 행운을 빈다. 그리고 받아들이는 것을 잊지 마십시오 ;-) – Prabhu

+0

대답이 유용하다면 upvote/accept 할 수 있습니까? – Prabhu