GNU C에서 recv() 시에 버퍼가 flush 되는지 궁금합니다.
글쓴이: morolty / 작성시간: 화, 2014/10/28 - 1:43오후
정말 별다른 코드는 없고
서버측에선
while(1){ nrecv = recv(); fprintf(stderr,"buff: [/%s], nrecv: [/%d]\n",buff, nrecv); ( %앞의 / 기호는 신경쓰지 말아주세요.. %s라고 쓰니 kldp에서 깨져서 임의로 넣었습니다..) }
만 하고 있고
클라이언트 측에선connect() 후에
1. write() 한 두세번하다가
2. close() 없이 강제로 끊어지게 만듬
그 상황에서 서버에선 recv 해도 버퍼가 flush 되지 않는거 같습니다.
fprintf로 찍어보니 recv의 리턴값은 0인데, buff는 마지막으로 클라이언트로 받았던 패킷을 계속 가지고 있네요..
원래 recv가 버퍼 플러쉬 작업을 해주지 않는 건가요?
Forums:
...
음, 코드가 깨진 것 같지만, recv나 read나 scanf나 기타 POSIX 혹은 C에서 기본적으로 제공하는 거의 모든 함수는 "버퍼 flush"를 해주지 않습니다.
즉 recv가 리턴 코드로 n을 돌려주면 버퍼의 첫 n 바이트만 유효합니다. (나머지 부분은 recv를 부르기 이전 상태로 유지될 것 같은데 이게 보장되는지는 잘 모르겠네요.)
계속 수정해서 본문내용을 보기좋게 고쳐보려 했는데 잘
계속 수정해서 본문내용을 보기좋게 고쳐보려 했는데 잘 안되네요 읽기 힘들게 글 써서 죄송합니다...
예를들어 클라이언트로부터 wirte()로 "1234567890"을 보냈을 경우,
서버측에서 recv()를 2바이트씩 받아들이면
12
34
56
78
89
으로 받아들이는걸로 기억하고 있는데 그러면 이건
1. 12를 받고, 12를 지워서 34567890이 남음
2. 34를 받고, 34를 지워서 567890이 남음
.
.
.
이런식으로 되는게 아니고 버퍼의 index를 받아오거나 아니면 다른방식이 되는거였던가요..???
...
물론 커널이 내부적으로 버퍼를 가지고 있습니다만 그건 커널의 버퍼이지 유저 프로그램의 버퍼가 아니죠.
커널이 네트웍 카드로부터 패킷을 받는 시점과 유저 프로그램이 recv를 부르는 시점은 서로 동기화가 안되니까, 커널이 유저 스페이스의 영역을 버퍼로 쓸 수는 없습니다. (커널 입장에서 볼 때 유저 프로그램이 그 버퍼를 계속 쓸 거라는 보장도 없고.)
그러니까 서버가 recv를 만약 2바이트씩 받아서 버퍼 1234567890이 생겼다고 해도 이 버퍼는 커널 내부에 숨겨져서 커널만 볼 수 있는 영역이지 사용자 프로그램이 관여할 수 있는 영역이 아닙니다.
음 ..
recv 가 0 을 리턴했다면 peer 가 shutdown 되었다는 뜻이죠.
게다가 buff 에는 아무런 값도 세팅하지 않았을테니..
buff 의 값을 찍어봐야 recv 호출하기 전에 buff 에 남아 있던 값이 그대로 출력될 뿐입니다.
연결이 끊어졌는데 굳이 socket 을 갖고 뭘 해보려는 시도는 별 의미 없을것 같네요. 그냥 close 하시면 됩니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
댓글 달기