|
^^:: 음.. 우선 네트워크 프로그램을 설계할 때 클라이언트 입장으로 시작한다면 개념이
단순해 질수 있습니다.
즉, 클라이언트가 요청하면 서버가 준다 뭐 이런식이죠.
클라이언트에서 스택을 검사해서 원하는 양의 패킷을 받는 예 입니다.(쓰레드 안에서 사용하셔야 합니다.)
int TZTCPConn::readExpectedSize( TIdTCPClient* pReader, TByteArray& bufRead, int iExpectedLen )
{
ZeroMemory( bufRead, sizeof(bufRead) );
int iStackBufSize = 0;
try
{
do
{
pReader->ReadFromStack( true, 1000, false );
iStackBufSize = pReader->InputBuffer->Size;
#ifdef APP_DEBUG
zout.trace("Thread[%d]: CMD-RES_INIT_INFO Check Stack Size : %d\n", ThreadID, iStackBufSize);
#endif
if( Terminated() )
{
throw Exception( "Termination Detected!" );
}
} while( iStackBufSize < iExpectedLen ); // expected packet size
pReader->ReadBuffer( bufRead, iExpectedLen );
}
catch( const Exception &e )
{
return 0;
}
return iExpectedLen;
}
★래미★ 님이 쓰신 글 :
: 답변 감사드립니다... __)*
: 문제가 있다는 것은 알겠으나, 해결책에 대해서는 도통 까막눈이네요 ㅠㅠ
: 우선 GStack 이라는 것을 어떻게 써야될지 모르겠어요...
: 세심한 답변에도 불구하고 죄송 ^^;(모르는게 죄라서요 ㅠㅠ)
: 무식한 방법으로 패킷사이즈를 고정시켜 통신하는 방법을 고려해야되겠다는 생각이 드네요..
: 도움이 많이 되었네요^^
:
: 황경록 님이 쓰신 글 :
: : ReadBuffer 를 사용하시면 BufSize 만큼 읽을 때까지 블럭상태가 됩니다.
: : 상대가 주는 패킷사이즈를 미리 알지 못한다면 ReadBuffer 를 사용하는데 문제가 있을것으로 보이는 군요.
: : 이럴 땐 GStack 을 사용해서 InputBuffer 의 크기를 미리 검사하고 검사하는 루틴에 인스턴스 종료에 대한 부분도 추가하고 Timeout 을 일정한 시간을 주는 것도 효율적이라 생각됩니다만...
: :
: : ★래미★ 님이 쓰신 글 :
: : : 아래 함수에서 ReadLn()으로 하면 읽히는데, ReadBuffer(Message, BUF_SIZE)로 하면
: : : 그 부분에서 멈추어 있습니다.
: : : 관련 Q&A를 찾아보려 했으나, 무식한 나머지 답이 비켜가는둣 하네요 ㅠㅠ
: : : 서버에서 여러개의 클라이언트를 상대하여 데이터를 listen 하고
: : : 또 다른 데이터를 주기도 할려구요(이부분은 타이머를 이용할려고 생각중입니다. 아직 미 구현..)
: : : 한데 클라이언트로부터 받을 데이터가 크기가 부정확한 binary(내부 프로토콜을 구성할 예정이구요)로 되어있어
: : : 이를 어떻게 받아들여야될지 모르겠네요 ㅠㅠ
: : : 서버랑 클라이언트 소스 첨부했습니다.
: : : 이 외에도 지적할 부분이 있으시면 많은 도움 주세요 __)/
: : :
: : :
: : :
: : : void __fastcall TForm1::TCPServerExecute(TIdPeerThread *AThread)
: : : {
: : : /*
: : : if( AThread->Stopped || AThread->Terminated ) return;
: : : TIdTCPServerConnection * con = AThread->Connection;
: : : AnsiString Message;
: : : try {
: : : Application->ProcessMessages();
: : : Message = con->ReadLn();
: : : MessageHandler(Message.c_str(), AThread);
: : : }
: : : catch(...) {
: : : // ListBox1->Items->Add("Error...");
: : : con->Disconnect();
: : : }
: : : */
: : :
: : : if( AThread->Stopped || AThread->Terminated ) return;
: : : TIdTCPServerConnection * con = AThread->Connection;
: : : char Message[BUF_SIZE];
: : : try
: : : {
: : : Application->ProcessMessages();
: : : con->ReadBuffer(Message, BUF_SIZE);
: : : // con->ClearWriteBuffer();
: : : MessageHandler(Message, AThread);
: : : }
: : :
: : : catch(...)
: : : {
: : : // ListBox1->Items->Add("Error...");
: : : con->Disconnect();
: : : }
: : : }
|