Jump to content
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr ×
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr
  • 0

socket 통신에서 active = true 했으나 작동이 안되고 있습니다.


kanggilnam

질문

안녕하세요 ?

제가 필요해서 socket 통신으로 프로젝터 전원 온오프 를 만들어 보고 있습니다.

------------------------------------------------------------------

상황:

192.168.0.120

192.168.0.121

192.168.0.122

192.168.0.123

4개의 아이피를 보유한 프로젝터가 있습니다.

120번 아이피와, 123번 아이피는 프로젝터가 없습니다.

121,122번 아이피는 프로젝터가 정상적으로 연결되어 있습니다.

----------------------------------------------------------------

전원 온 버튼을 클릭 -> 첫번째 120번 아이피를 읽고 active = true 로 활성화 시킴 이때 타이머로 5초간 connect 가 없으면 121번 아이피를 프로젝터 전원 on 하라고 명령을 줍니다.

 

  if ClientSocket1.Active then
    ClientSocket1.Active := False;
  Sleep(1000);
  ClientSocket1.Host := ip;
  ClientSocket1.Port := StrToInt(port);
  ClientSocket1.Active := True;

  Timer1.Enabled := True; // 5초 동안 타이머로 연결 유무 첵

-------------------------------------------

타이머 5초 첵 루틴

  PnlSec.Caption := IntToStr(5 - ConChkSec);

  if ip = ClientSocket1.Socket.RemoteAddress then  // 서버에서 5초 이내 보내온 서버 아이피와 클라이언트에서 on 요청한 아이피가 동일하면 정상적으로 통신연결이므로 다음 121번 아이피로 넘어가라
    Timer1.Enabled := False
  else
  begin // 물리적으로 프로젝터가 랜카드나 케이블 이상으로 또는 완전 고장으로 전혀 네트워크 연결이 안되서 5초 이네에 대답이 없을때 에러로 보고 스킵하고 다음거 실행
    if (ConChkSec = 5) then
    begin
      if ip <> ClientSocket1.Socket.RemoteAddress then
      begin
        ConChkSec := 0;
        Timer1.Enabled := False;

        Inc(TimerNextARow);
        meoLog_send.Lines.Add('----------------------------------------------------------------------------------------- ');
        meoLog_send.Lines.Add(' '+ IntToStr(Seqno)+').....' + DateTimeToStr(now) + ' : '
                                 + 'Timer Routine Power All On : 네트워크 연결 상태를 확인하세요!  '
                                 + ip + ' : ' + port);
        meoLog_send.Lines.Add('----------------------------------------------------------------------------------------- ');
        meoLog_send.Lines.Add(' ');

        if TimerNextARow <= (ASG_ComList.RowCount - 2) then
        begin
          ip := trim(ASG_ComList.Cells[3,TimerNextARow]);
          port := ASG_ComList.Cells[4,TimerNextARow];

          Sleep(1000);
          ClientSocket1.Host := ip;
          ClientSocket1.Port := StrToInt(port);
          ClientSocket1.Active := True;
          meoLog_send.Lines.Add(' '+IntToStr(Seqno)+').....' + DateTimeToStr(now) + ' : '
                                 + 'Timer Routine Power All On for IP And Port ->  ' + ip + ' : ' + port);
          meoLog_send.Lines.Add(' ');
          NextARow := TimerNextARow;
          Timer1.Enabled := True;
        end;

      end;

    end
    else
      ConChkSec := ConChkSec + 1;
  end;
 

 

------------------------------------------------------------------------------------------------------

문제점 :

121번 아이파와 122번 아이피에는 정상적으로 프로젝터가 연결되어있습니다.

위의 5초 첵 루틴에 의하여 120번은 연결이 안되어 있으므로 에러를 띄우고 121 번 아이피로 넘어갑니다.

121번 아이피의 프로젝터 전원 on 을 실행하여 정상적으로 on 이 실행됩니다.

121번 아이피의 프로젝터 전원 on 되고 약 20초 후 자동적으로 socket 이 disconnect 됩니다.

socket이 정상적으로 disconnect 되면 다음 122번 아이피를 active 시키려고 하였으나 아무런 반응이 없습니다.

도저히 이해가 안됩니다.

메모장에 아이피를 기록해 놓아서 122 아이피로 active 시켜라고 명령이 수행되었습니다.

        ip := ASG_ComList.Cells[3,i];
        port := ASG_ComList.Cells[4,i];
        meoLog_send.Lines.Add(' '+IntToStr(Seqno)+').....' + DateTimeToStr(now) + ' : ' + 'Disconnect Routine Power All On IP And Port ->  '
                               + ip + ' : ' + port);
        meoLog_send.Lines.Add(' ');
        TimerNextARow := i;
        if ClientSocket1.Active then  // 전 생성한 소켓을 false 시킨다
          ClientSocket1.Active := False;
        Sleep(5000);
        ClientSocket1.Host := ip;
        ClientSocket1.Port := StrToInt(port);
        ClientSocket1.Active := True;
        ConChkSec := 0;
        Timer1.Enabled := True;

 

 

아래는 Disconnect 루틴의 소스 전체입니다.

---------------------------------------------------------------------------------------------------------------

procedure TfrmClient.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  i: integer;
begin

  Inc(Seqno);
  meoLog_receive.Lines.Add(' '+IntToStr(Seqno)+').....' + DateTimeToStr(now) + ' : ' + 'DisConnected IP  -> '
                              + ClientSocket1.Socket.RemoteAddress + ' : ' + IntToStr(ClientSocket1.Socket.RemotePort));
  meoLog_receive.Lines.Add(' ');

  with ASG_ComList do begin
    for i := 1 to RowCount - 2 do
    begin
      if trim(Cells[3,i]) = ClientSocket1.Socket.RemoteAddress then
      begin
        CreatePicture(7,i,True,ShrinkWithAspectRatio,0,AdvGrid.haCenter,AdvGrid.vaTop).LoadFromFile('./NO.png');
      end;
    end
  end;

  if (BtnAll = 'Y') then
  begin
    Inc(NextARow);
    for i := NextARow to  ASG_ComList.RowCount - 2 do
    begin
      try
        ip := ASG_ComList.Cells[3,i];
        port := ASG_ComList.Cells[4,i];
        meoLog_send.Lines.Add(' '+IntToStr(Seqno)+').....' + DateTimeToStr(now) + ' : ' + 'Disconnect Routine Power All On IP And Port ->  '
                               + ip + ' : ' + port);
        meoLog_send.Lines.Add(' ');
        TimerNextARow := i;
        if ClientSocket1.Active then  // 전 생성한 소켓을 false 시킨다
          ClientSocket1.Active := False;
        Sleep(5000);
        ClientSocket1.Host := ip;
        ClientSocket1.Port := StrToInt(port);
        ClientSocket1.Active := True;
        ConChkSec := 0;
        Timer1.Enabled := True;

      except
        on e: Exception do
        begin
          Application.MessageBox(PChar(e.Message), PChar('에러'), MB_ICONERROR + MB_OK);
        end;
      end;
    end;
  end;

end;

이 댓글 링크
다른 사이트에 공유하기

8 answers to this question

Recommended Posts

  • 0

소켓통신에서 Sleep() 명령어는 정상적으로 작동 되지 않습니다. 

Sleep() 메소드는 윈도우 이벤트 방식의 멀티태스킹 이전 아주 오래전에 나왔던 시스템을 정지 시키는 명령어 입니다.

타이머를 이용 해서 대기 시간을 카운터 해 보세요.

이 댓글 링크
다른 사이트에 공유하기

  • 0

sleep(5000)을 삭제해도 똑같습니다. sleep(5000)을 추가한 이유는 socket connect를 Disconnect 하고 잠시 시간차를 두고 active 하기 위하여 추가한 것입니다.

sleep(5000)이 있고 없고는 위의 증상과 관련이 없습니다.

왜 active = true 했는데 connection 이 발생하지 않는지 이유를 모르겠습니다.

        ClientSocket1.Active := True;
        ConChkSec := 0;
        Timer1.Enabled := True;

active = true  가 실행되고 타이머가 작동되면서 5초동안 connect 여부를 다시 첵 합니다.
122 아이피는 프로젝터가 연결되어 있어서 connect 가 발생해야 하는데 전혀 어떠한 반응이 없습니다. ㅠㅠ

이유를 정말 모르겠습니다.

조언 부탁드립니다.

 

 

Edited by kanggilnam
이 댓글 링크
다른 사이트에 공유하기

  • 0

질문 내용이 같은 소스로 장비가 어떤것은 연결이 되고 어떤것은 연결이 안된다는 것인가요 ?

같은 소스로 되는 장비가 있고 안되는 장비가 있다면 장비상태를 점검해야 하고

모든 장비가 다 안되다면 장비 연결하기 전에 소켓서버를 하나 만들어서 테스트 해서 소스코드가 정상작동 하는지 확인해보고 장비와 테스트 하는게 좋습니다.

 

이 댓글 링크
다른 사이트에 공유하기

  • 0

4개의 아이피중 2개의 아이피에 프로젝터가 lan으로 연결되어 있습니다.

첨부의 화면을 보면 하단 그리드에 개별 on 버튼이 있습니다. 이 버튼으로 on 시 개별로 잘 작동합니다.

그러나 개별로 눌러서 on 하는게 귀찮아서 상단의 on 이미지로 한꺼번에 프로젝터 전원을 on 하려고 하는 것 입니다.

for 문으로 그리드에 나온 프로젝터 갯수만큼 loop 돌면서 active 시키는 것 입니다.

랜 케이블은 정상적으로 연결되어 있고 장비 또한  정상적입니다. 하나씩 개별로 power on off 시 잘 작동합니다.

 전체 전원 on 버튼으로 만들어서 실행 시 위와 같은 문제가 발생했습니다.

문제는 121번 아이피의 경우에는 정상적으로 전원이 on 됩니다. 그 다음 122번 아이피 주고 active = true 했는데 connection 반응이 전혀 없습니다.

123 아이피는 연결이 안되어 있어서 120번 아이피처럼 타이머 5초 루틴에서 

        meoLog_send.Lines.Add('----------------------------------------------------------------------------------------- ');
        meoLog_send.Lines.Add(' '+ IntToStr(Seqno)+').....' + DateTimeToStr(now) + ' : '
                                 + 'Timer Routine Power All On : 네트워크 연결 상태를 확인하세요!  '
                                 + ip + ' : ' + port);
        meoLog_send.Lines.Add('----------------------------------------------------------------------------------------- ');

이 루틴에 걸려서 메모장에 메시지를 뿌려줍니다.

화면.png

이 댓글 링크
다른 사이트에 공유하기

  • 0

장비 통신 프로그래밍을 하다 보면 알 수 없는 이유로 통신이 안되는 경우가 매무 많습니다.

이떄는 원인을 분석해서 이유를 못찾으면 같은 방법으로 하지 말고 여러가지 다른 방법으로 시도해 보는게 좋습니다.

장비대수가 동적이라도 TClientSocket 을 동적으로 생성 할 수도 있고 최대수 만큼 컴포넌트를 가져다 놓아도 되고 모두 가능 합니다.

TClientSocket이 장비와 궁합이 안 맞으면 3rd Party 컴포넌트도 있으니 한가지 방법에 머무르지 마시고  여러가지 방법으로 시도해 보세요.

이 댓글 링크
다른 사이트에 공유하기

  • 0

indy 로 바꿔서 해보려고 수정하고 있습니다.

아래의 코드는 ClientSocket 에서 Error 발생 처리하는 event 입니다.

indy client의 IdTCPClient1 에서 Error 발생 처리하는 event 가 있나요 ?

IdTCPClient1 에서 connect time 을 5초로 지정해서 그 사이에 연결이 안되면 물리적 문제로 판단하여 다음으로 스킵하려고 합니다.

이때 timeout error 가 발생해 메시지 박스가 나타납니다. 그것을 없애려고 합니다.

clientsocket 컴포넌트는 error 이벤트가 있어서   ErrorCode := 0 값주면 메시지 없이 처리됩니다.

 

procedure TfrmClient.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  ErrorCode := 0;
end;

 

 

 

 

 

Edited by kanggilnam
이 댓글 링크
다른 사이트에 공유하기

이 토의에 참여하세요

지금 바로 의견을 남길 수 있습니다. 그리고 나서 가입해도 됩니다. 이미 회원이라면, 지금 로그인하고 본인 계정으로 의견을 남기세요.

Guest
이 질문에 답변하기...

×   서식있는 텍스트로 붙여넣기.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   이전에 작성한 콘텐츠가 복원되었습니다..   편집창 비우기

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

중요한 정보

이용약관 개인정보보호정책 이용규칙 이 사이트가 더 잘 작동하기 위해 방문자의 컴퓨터에 쿠키가 배치됩니다. 쿠키 설정 변경에서 원하는 설정을 할 수 있습니다. 변경하지 않으면 쿠키를 허용하는 것으로 이해합니다.