소켓 프로그래밍 첨하는데 버퍼링같은걸 어떻게 구현할지 모르겠습니다 ㅠㅠ
안녕하세요. 맨날 눈팅만 하다가 처음으로 가입해서 포럼주제 써봅니다.
KLDP 위키의 BeeJNetworkProgramming 문서 보면서 소켓 프로그래밍 공부하고 있습니다.
번역해주신분께 너무나 감사할 따름입니다 ㅎㅎ
제가 만들고 있는 프로그램은
i)사용자로부터 URI를 받아서
ii)해당하는 HTML문서를 네트워크에서 받아오고
iii)그 문서를 파일로 저장하는
프로그램입니다.
우선 i)번 과정은 대부분 된것 같은데, ii)번 과정이 문제입니다.
프로그래밍 연습할때는 끽해야 자료 크기가 바이트단위에서 노는데, 인터넷에 돌아다니는 html문서는 1KB가 넘는 경우가 많습니다 ㅠㅠ
이 커다란 자료를 받아오려고 두가지 방법을 생각해 봤는데,
1. 엄청나게 커다란 변수를 만든다!
2. 조금씩 받아와서 합친다!
아무래도 1번은 좀 아닌것 같고, 2번 방법을 써야될것 같더라구요.
조금씩 받아오는걸 어떻게 하면 좋을까요?
문서를 보면 recv()함수 인자를 통해 받아올 최대 사이즈를 정할수 있다고 하는데, 그렇게 사이즈를 정해놓으면 (예를 들어 256바이트라 했을때) html문서 맨앞의 256바이트밖에 안받아옵니다.
그 이상을 계속해서 받아오는 방법을 모르겠어요.
kldp분들께 욕을 얻어먹지 않기 위해 구글 검색도 해보았지만, C에서 구현된 http라이브러리 소개글만 죽죽 읽다가 허탕쳤습니다...
아무래도 이걸 버퍼링이라고 부르는 모양인데, 버퍼링을 어떻게 구현해야 하나요? (버퍼링이 아닐 수도 있습니다. 버퍼링이란 용어는 그냥 무시해주세요.)
소스는 별 도움이 될것같지 않아서 (send나 recv하는 코드가 아예 없습니다. 서버에 connect하는 부분까지만 만들었어요) 올리지 않기로 했습니다.
구구절절 하소연 비슷한 질문글 읽어주셔서 감사합니다.
BeeJNetworkProgramming 자료공유가능한가요?
안녕하세요 저도 눈팅만하다가 님이 쓰신글을 보고 글을 적어봅니다.
BeeJNetworkProgramming 자료 공유가 가능하신지요? 함께 연구해보고 싶네요.
kldp 위키
kldp 위키 페이지입니다.
https://wiki.kldp.org/wiki.php/BeeJNetworkProgramming
Signature :) - "여유를 갖고 행동하되 게을러지지 말자"
recv으로 256바이트를 읽은 다음에 recv를 한
recv으로 256바이트를 읽은 다음에 recv를 한 번 더 호출하면 그 다음 부분부터 받을 수 있습니다. 받을 게 남아 있다면 말이죠. 직접 여러 번 호출해서 받은 데이터를 출력해보세요.
(받을 게 남아있지 않은데 recv를 호출하면, 소켓 속성에 따라 다르긴 하지만 블록당할 수도 있으니 주의가 조금 필요합니다.)
감사합니다!
말씀하신대로 원하는만큼 들어올때까지 recv()하는 방식으로 해결했어요. 소켓 블록은 한번 공부해봐야겠네요.
https://msdn.microsoft.com/ko
https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms740121(v=vs.85).aspx
Return value
If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero.
Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
정확히 MSDN에 설명되어 있습니다.
오류가 발생하지 않았다면 recv는 수신된 수의 크기를 반환할 것이고 버퍼 포인터는 수신된 데이터가 들어있을것이다
만약 연결이 끊겼다면(더 이상 받을 데이터가 없다면 이라고 해석하시면 되겠네요) 0을 반환할것이다.
그 외의 SOCKET_ERROR을 반환했거나 그리고 다른 오류 코드들은 WSAGetLastError을 통해 가져올 수 있을것이다.
그냥 간단하게
으로 하셔서 받으시면 안되나요? SOCKET_ERROR도 검사하는 루틴 포함시켜서.
정확히 사용해보지 않아서 모르겠지만 위와 같은 방법으로 0이 클때까지 돌리시면 될건데요
0이면 받을 데이터가 없는거고 음수면 오류가 뜬거니깐 WSAGetLastError을 사용하셔서 적절히 대응하시면 될것같고
정확히 밑의 예제에 구현이 되있네요.
아마 검색해보시면 가장 효율적으로 데이터를 송수신할 수 있는 크기가 어디 나와있을겁니다.
https://en.wikipedia.org/wiki/TCP_tuning
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=17&MAEULNo=8&no=59261&ref=59253
http://egloos.zum.com/psjHello/v/103770
뭐 그냥 전송할 크기를 참고해 입맛에 따라 구현하시는게 맞을거라 봅니다.
허걱 이런 상세한 답변을...!
대충 256바이트 정도로 해서 데이터 받았어요.
윈도랑 리눅스랑 소켓함수는 많이 비슷하네요. 감사합니다.
댓글 달기