|
Socket 에서 데이터를 읽어오는 부분이 어디 있나요?
설마 ProcessPacket() 에서 하시는것은 아니겠죠?
짐작컨데 ProcessPacket() 에서 하는듯 하군요. ServerExecute 에 Socket에서 데이터를 읽는 부분이 없으니까요.
CriticalSection 이나 Synchronize 에 대하여 정확히 아셔야 합니다. 또한 Indy의 Thread 가 어떻게 도는지 아셔야 합니다.
일단 Server (Client도 마찬가지 입니다만) ServerExecute 에 인디 프로세스가 옵니다. 물론 AThread 를 인수로하여
이 안에 socket 정보를 가지고 옵니다.
ServerExecute 에 와서
Socket 에서 데이터를 읽으러 들어가야죠.. AThread->Connection->Socket->Read 정도 되는 함수들일 것 입니다.
이렇게 읽으러 들어가면 프로세스가 그 안에서 멈추어 있습니다.
흔히 client socket은 마냥 기다리지 않고 timeout 을 설정하여 해당 timeout 이 지나면 해당 동작을 무시하고 read 에서 나옵니다. 그러나 server socket은 데이터가 올때까지 기다립니다.
기다리다가 원하는 데이터가 오면 해당 함수를 탈출하여 나옵니다. 즉 다음 라인으로 진행하죠.
또한 비정상적인 client 연결 종료도 있을수 있는데,, 이경우도 thread를 빠져 나옵니다. 그러나 에러가 걸려 나오기 때문에 try ... catch... 로 묶어 주셔서 정상적으로 나온건지(원하는 데이터가 옴) , 아니면 기타 다른요인으로 에러가 난것인지를 판단해야 합니다.
아래의 소스에서 보면 무조건 critical section으로 들어갑니다.
그러면 다음 소켓은 해당 critical section으로 들어갈 수가 없습니다.
즉 소켓 하나만 돌겠죠.. 나며지는 기다리고 ,, 데이터 수신도 못하고요..
앞선 socket이 데이터를 받아서 나온후 critical section을 빠져 나와야 다음 소켓이 들어가겠죠.
critical section이든 synchronize 든 오랜시간을 머무르시면 않됩니다.
아래의 경우 먼저 들어간 socket이 데이터를 마냥 기다리고 있으면 다른 소켓들은 그냥 앞선 socket 끝나기만
기다려야 겠죠.
데이터가 가끔 오면, 그리고 각 socket들이 서로 다르게 오면 프로세스가 돌 수도 있습니다만.
아마 연결하는 client쪽에서 time out 아 자주 발생할 수 있을 듯 합니다.
Thread , CriticalSection, Synchronize 등등 좀 어려운 분야의 코딩입니다. 그러므로 좀더 정확한 코딩이 있어야만
문제가 없을듯 합니다.
소켓에서 데이터 읽은후 DB QUEUE 에 넣는 부분만 critical section으로 묶으세요..
수고하세요...
용맨소녀 님이 쓰신 글 :
: 예전에 Indy9의 OnExecute에서 ADO쓸때 동기화에 관한 질문을 했었습니다. ADO호출시 Synchronize를 해야한다는 것이었는데요.. (전 OnExecute이벤트가 하나씩 순차 호출되는걸로 잘못 알고..ㅡ.ㅡ)
:
: 그럼... 패킷쪽도 같은 식으로 처리해야 하는거란 뜻인데요.. 그런거라면 Synchronize같은거 안쓰고 아예 패킷처리부를 크리티컬 섹션으로 덮어야하는게 깔끔하지 않나 생각됩니다. DB는 큐를 쓰면 될거고요..
:
: 예를 들어서.. 이렇게 한다면 대충 무난할까요? 지금 만드는건 패킷이 띄엄띄엄오는 거라 성능은 신경안쓰고 만들고 있지만.....
:
: 암튼, 아래 방식으로 한다면 크레이지아케이드류같은 게임에서 1000명은 커버할려나요? ^^
:
: 경험많으신 고수님들 답변 부탁드립니다..
:
: void __fastcall TWin_Main::ServerExecute(TIdPeerThread *AThread)
: {
: EnterCriticalSection(&Cs);
: ProcessPacket(AThread); // 이 안에서 DB 관련은 큐로 처리..
: LeaveCriticalSection(&Cs);
: }
|