안녕하세요~iocp에 관해서 질문올립니다~!ㅎㅎ
안녕하세요 ㅎㅎ
오랫만에 네트윅 코드를 짜고있습니다;;ㅎㅎ
예전에 IOCP로 한번 짜보고 다시 짜고있는데;;구조상?IOCP 에 관련된 질문이 여럿 떠오르네요 ㅎㅎ
여러 자료도 찾아보고 구글도 찾아보고;;;답은 대충나왔지만 그대로 정리차원에서 확답을 듣고싶어서
여기 글을 올려봅니다 ㅎㅎ
우선 현재 구조를 설명드릴께요
처음엔 worker thread x 2 와 send 및 parse쓰레드를 따로 있는 구조로 하려했습니다.
하지만 각 쓰레드간의 자원(큐) 참조시 안전한쓰레드를 위해 크리티컬 섹션을 썻어야했습니다.
당연한거겠지요. 하지만 욕심이 생겨서 이 크리티컬 섹션을 최대한 안쓰고 대신 io 작업과 비즈니스 로직부분을
나두던것을 worker thread안에 몰아넣고(즉 parse를 없에고) 대신 워커를 여러개 하기로 마음먹었습니다.
그러다가 또 문제점이 생긴게(아니 제가 만든건조) 문서를 읽다보니 wsarecv를 한솟켓에 여러번 걸수 잇더군요
즉 한솟켓에 한 워커쓰레드에 한번씩 wsarecv를 거는것이아니라
첨 프로그램 시작후 접속이 들어오면 그 접속에 wsarecv를 여러개 걸어주었습니다.
그 이유는 1개의 io작업이 끝나도 바로 이어서 다른 io작업이 들어올수있을것이라는 추측때문이였습니다.
즉 1개의 io작업을 워커가 처리하는 사이에 다른 io작업이 들어온다면 그에따른 버퍼가 미리제공되어있어야만
더 빨리 네트워크 데이터 처리(io작업)이 이루어질거라는 생각에서였습니다.
(한문서에서 버퍼가 제공되어있다면 그 버퍼로 직접 들어가고 그렇지않으면 기존방식대로의처리가된다구함)
덕분에 한솟켓에 대해서 여러 워커가 완료처리를 받을수있게 된것같으며 이경우 순서성에 문제가 되더군요..
그 순서성을 해결할 수있는 방법을 생각해보니 보내는 시점에서 최대 사이즈를 정해서 wsasend를 하는게
낫지 않나 생각이 들었습니다. 즉 보내는곳에서 서버(버퍼최대사이즈 5120)에게 최대 버퍼 사이즈 밑으로만
데이터를 보낸다면 받는곳에선 딱 그만큼만 받을것이란 생각도 들었구요 즉 버퍼가 넘을 만큼 들어오지
않기때문에 받는 서버에서 문제가 없을것이란 생각이 들었습니다..
하지만 여기는 의심이 굉장히 많이 드네요..
wsarecv를 여러번 걸음으로써 빠른 데이터 처리 효율은 얻었지만 순서성을 잃었으며
그 순서성을 해결하고자 최대 버퍼 사이즈를 정해서 그 밑으로만 데이터를 보내게 만들었습니다.
또한 wsarecv를 한솟켓에 여러 쓰레드에서 동시에 걸 확률이 생겼으며
wsasend도 또한 여러 쓰레드에서 한 솟켓에 동시에 걸 확률이 생겼습니다.
아직 테스트 전입니다만..;;대부분 어떻게 하는지 궁금합니다..
아 그리고 또 어떤문서에서 어떤분이 wsasend를 3개월동안 보내기 한결과 10번의 전체 전송을 못한 경우가
있다고하더군여 ㅡㅡ;;;;;;;;;;;;;;;;;;;;;;이해할수 없는건 tcp의 특성을 그대로 가지고있다면..
다보내야하는게 당연한것같은데..아님 솟켓이 끊겼을경우를 말했을까요??
또한 wsarecv 도 완전히 못받을 가능성이 있을까요??버퍼가 충분한경우를 말합니다..
음 참 잼있으면서도 고민할게 많네요..많은 문서를 찾아봣지만 확답을 내려주시는 분이 없어서;;;
이렇게 글을 올려요;;;
그럼 답변 부탁드려요~! 아하 즐거운 명절 되세요~!!!
/////////////////////추가///////////////
wsarecv를 한번이 아니라 한솟켓에 여러번 걸었을경우
들어오는 데이터의 순서성을 알수가 없다는것을 염려하고있습니다..즉 순서또한 정확하지않고 완료알림순서또한
정확하지 않기때문에 데이터가 잘려서 두번에 걸쳐서 들어올경우 문제가 크다는경우도..
조합할수 없기때문입니다.;
그래서 어쩔수없이 최대 사이즈를 정해서 send recv를 할경우 물론 보내는쪽에서 받는 서버입장에선
그 버퍼 사이즈안에서만 다 받는다고 생각하거든요(이건경험상) 하지만 여기도 잘려서 온경우 다른
워커에서 잘려서 온게 들어온다한들..순서를 알수없기에..무모하지않나라는..생각입니다.
시퀸스를 넣는다해도 그건 잘려서 들어왓을때 아무 의미가 없지요;;;
물론 제가 가정한 모든 범위는 wsarecv를 여러번 걸어놓았을때 이야기입니다.
한번만 걸어놓았다면 잘려서 들어와도 다시 recv걸으면 순서대로 들어오는건 당연하겟지요
이경우는 반대로 send시에 잘려서 못갔을경우만 문제가 되겟지요..왜냐하면 저같은경우엔
wsasend를 워커내부에서 보내는경우도있지만 ui에 어떤 특정행동에 의해서 큐처리에 의해
보내는경우도 있거든요..물론 이문제점은 위의 wsarecv에서도 똑같은 문제점이지요..
어쨋든 테스트에 의해서 해결을 해봐야할듯한데;;;참-_-
wsarecv를 걸었을때 혹은 sendrecv를 걸었을때 그걸 다 보내거나 받는다는 보장만 있어도
수훨할것같같은데 참 잘만들었지만 애매한 구조입니다..;;
///////////////////////////////////
데브에다가 글을 올렸다가 제대로 된 답변이 안달려서 여기에다가 글을 올려봅니다~!^^
경험있으신분들 답변좀 ㅎㅎ;;개발에 도움이 될것같아요;;
iocp...
일단 질문하신 답변은 아니란것부터 알려드리겠습니다.
1-send/recv, n-send/recv 문제는 게시판에 글 타레 올라올때마다 여러 추가 질문이 올라오는 부분이죠.
안전하게 하시려면 그냥 1-send/recv 가 좋겠죠.
제 경우는 recv는 1-recv, send는 n-send 를 사용하면서
1-recv의 성능문제가 걱정되서
recv는 TCP 버퍼를 사용하고 send는 0으로 설정합니다.
댓글 달기