원하시지 않는 부분까지 제가 관혀할 일이 아닌데.. 이점 죄송합니다.
그냥 제가 보는 관점에서 말씀드립니다..오해 없으셨으면 합니다.
일단 채팅 샘플을 가지고 시작을 하셨는데요. 어떤 면에서 장비와 채팅을 하는것이라 생각하면 상관은 없습니다만.
지금 작성하시는 코드가 장비를 컨트롤 하시는것 같습니다.
흔히 장비를 PC로 콘트롤 할 경우 장비가 일종의 서버가 되고 PC가 일종의 클라이언트가 됩니다.
장비는 분명 server socket 를 열어 pc의 연결을 기다리고 있겠죠. 그런관계로 아래의 프로그램에서 TCP Client Socket 을 사용하신것이고요.
이런 종류의 프로그램에서 장비와 PC의 통신은 흔히
1. PC 가 장비에 연결 요청하여 연결 수락 -> 연결 (Socket 하나가 만들어지죠)
1.5 장비는 PC로 부터의 수신을 위하여 receive 대기
2. PC 가 장비에 질의 (Query, 질의 종류에 따라 2.5로 갑니다)
2.5 PC는 Receive 상태로 대기(Indy 이니까 thread 로 들어 갑니다)
3. 장비는 PC로부터 데이터를 받아 처리하고 결과를 PC에 응답 (Response)
3.5 장비는 1.5로 가겠죠
4. PC는 장비로 부터오는 값을 수신
4.5 장비로부터 온 값을 처리후 다음 행동 결정하여 5번에 적용하겠죠
5. 2번으로 분기 또는 종료
가 될듯 합니다.
위의 순서는 대략적으로 적은것입니다만.
간단히 PC는 장비에 질의를 하여 그 응답이 있는 질의면 receive 로 빠져야 하고 그렇지 않은 단순 수행 명령
이면 다음 행동을 해야 겠죠.
이러한 시퀀스에서 timer 는 그 용도가 없습니다.
채팅 프로그램에 timer 를 쓴다는 것은 P2P 를 약간 흉내내기 위한 것 입니다.
네트웍 소켓을 이용한 통신 프로그램은 구성상 (FULL / HALF 에 따라서)은 다소 다른구조일 수 있습니다.
궂이 위와 같이 구성을 않하고 아래의 프로그램과 같이 한다고 해도.. 몇가지 부분이 문제를 일으킵니다.
우선 타이머가 들어가서 소켓이 receive 대기로 갑니다. (Socket 연결 여부는 사실 여기서 의미가 많이 없습니다, 끊어지면 타이머를 끄셔야 됩니다) , 앞에분이 지적하셨듯이 Connected 를 이중으로 하셨고요. 도는데는 아무 지장 없습니다만...
receive 부분에 try catch 로 timeout 에 대한 처리를 하셨고요.
timer 를 끄지를 않으시고 receive 로 들어가셨습니다. timeout 걸릴때 또는 연결 자체가 않되었을경우 timer를 끄셨습니다.
timer 와 indy 의 thread은 별개의 것 입니다.
이미 indy 가 receive 를 위하여 thread로 들어갔으며 timer 는 계속적으로 돌게 되겠죠.
receive 로 들어가기 전에 timer를 끄셔야 합니다.
아래와 같이 어떻게해서든 송수신을 하게 한다고 하여도.. 그 안정성에는 보장을 못할 수 있습니다.
정확한 송수신 protocol 규칙을 정하셔서 처리하시는 것이 장비를 보호하고 프로그램이 어느 상황에서든 문제없이
돌아가도록 하는 지름길이 아닐까 합니다.
아래의 코드가 전혀 잘못됬다는 것은 아니니 오해 없으시길 바랍니다...
Kenzuro 님이 쓰신 글 :
: 먼저 답변 감사합니다!!
:
: 제가 버전을 안 써놨었네요 ㅎ 버전은 Indy9입니다.
:
: 아래 코드와 같이 구현하지 않는다는 것을 잘 이해 못하겠습니다.
:
: 다른 데모 버전 보니깐 스레드로 구현을 해놨던데..
:
: 타이머가 아니라 스레드로서 구현한다는 것인가요?
:
:
:
: 둘리.CSIEDA 님이 쓰신 글 :
: : Indy9 인가요? Indy9 blocking mode (indy10 도 마찬가지지만요)라면
: : 코딩이 잘못 되셨습니다(꼭 잘못된 것은 아니고, 아래의 코드와 같이 구현하지 않거든요).
: : 우선 확인 부탁 합니다.
: :
: :
: :
: : Kenzuro 님이 쓰신 글 :
: : : 안녕하세요 Builder 초보 Kenzuro 입니다.
: : :
: : : 장비에서 값을 받아오는데.. 시간값을 명령어로 보내면 장비에서 데이터를 보내 주고 있습니다.
: : :
: : : 기본 소켓으로는 잘 되고 있었는데요. 그것을 인디로 바꾸 싶어서 공부를 하고 있습니다.
: : :
: : : 데이터는 D,M1,N001,40,30,40,0,N002.... 이런식으로 들어오는데 N060까지 들어옵니다.
: : :
: : : 채팅 데모 버전을 약간 수정해서 만들어봤는데요. 장비에 명령어를 보내도 감감 무소식입니다..
: : :
: : : 값을 받는 방법이 틀린건가요?? 도움 좀 주세요~
: : :
: : : 제가 만든 소스 첨부하겠습니다.
: : :
: : :
__fastcall TForm1::TForm1(TComponent* Owner)
: : : : TForm(Owner)
: : : {
: : :
: : : IdSocketClient->Host = "192.168.0.50";
: : : IdSocketClient->Port = 5001;
: : : IdSocketClient->Connect();
: : : Sleep(1000);
: : :
: : : if(IdSocketClient->Connected() == true){
: : : ReceiveMemo->Lines->Add("Socket Connect Success\n================================\n");
: : : }else{
: : : ReceiveMemo->Lines->Add("Socket Connect fail\n================================\n");
: : : }
: : : }
: : : //---------------------------------------------------------------------------
: : :
: : : void __fastcall TForm1::SendMessageClick(TObject *Sender)
: : : {
: : : if(SendEdit->Text != ""){
: : : IdSocketClient->WriteLn(SendEdit->Text);
: : : Sleep(100);
: : : ReceiveMemo->Lines->Add("Send : " + SendEdit->Text+ "\n================================\n");
: : : SendEdit->Text = "";
: : : }
: : : }
: : : //---------------------------------------------------------------------------
: : : void __fastcall TForm1::ReceiveTimerTimer(TObject *Sender)
: : : {
: : : if(IdSocketClient->Connected()){
: : : static int errorcnt = 0;
: : : AnsiString Msg;
: : :
: : : if(!IdSocketClient->Connected())
: : : return;
: : :
: : : try{
: : : Msg = IdSocketClient->ReadLn("", 5);
: : : //IdSocketClient->ReadBuffer(Msg, 1024)
: : : }catch(...){
: : : errorcnt++;
: : : if(errorcnt > 4){
: : : ReceiveTimer->Enabled = false;
: : : ReceiveMemo->Lines->Add("IdSocketClient Error\n================================\n");
: : : }
: : : }
: : :
: : : if(Msg != ""){
: : : ReceiveMemo->Lines->Add("Recv : " + Msg +"\n================================\n");
: : : Msg = "";
: : : }
: : : }else{
: : : ReceiveTimer->Enabled = false;
: : : ReceiveMemo->Lines->Add("IdSocketClient DisConnect\n================================\n");
: : : }
: : : }