티스토리 뷰

- 컴파일러: C++Builder 2010 / Indy 10.5.5
- 쓰레드를 사용한 인디의 클라이언트를 동적생성
- 쓰레드는 소켓으로 받은데이터를 처리하기 위한 부분
- 데이터 보내는 부분은 Timer를 사용
- 데이터는 HEX값을 사용

먼저 File -> New ->Other.. 에서 쓰레드를 만들고


쓰레드의 클래스이름을 정하고


자동생성된 Unit 에서 다음 코드를 작성 ^^
_sockCthread.cpp

#pragma hdrstop #include "_sockCthread.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(&UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall sockCThread::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------
__fastcall sockCThread::sockCThread(bool CreateSuspended)
 : TThread(CreateSuspended)
{
 int i;
 //쓰레드 가장 높은단계
 Priority = tpTimeCritical;
 //인디 TCP/IP 클라이언트 동적생성
 IdTCPClient1 = new TIdTCPClient(NULL);
 //타이머 동적생성
 sendTimer = new TTimer(NULL);
 sendTimer->Interval = 200;
 sendTimer->OnTimer = userOnTimer;
 sendTimer->Enabled = true;  //요구프로토콜 초기화
 sendByte[0] = 0x01; //ID
 sendByte[1] = 0x61; //Function
 sendByte[2] = 0x16; //Length
 sendTByte.Length = 3;
 for(i=0;i<3;i++) sendTByte[i] = sendByte[i];  isendCnt=0;
 ireadCnt=0;
 iTag = 0;
}
//---------------------------------------------------------------------------
// 소멸자
//---------------------------------------------------------------------------
__fastcall sockCThread::~sockCThread()
{
    delete sendTimer;
 delete IdTCPClient1; }
//---------------------------------------------------------------------------
// Start
//---------------------------------------------------------------------------
void __fastcall sockCThread::Execute()
{
 //---- Place thread code here ----
 int ilen;
 int i;
 while(!Terminated) {
  IdTCPClient1->ReadTimeout = 100; //무한히 기다리지 않도록 time out을
  //통신이 연결되어 있고
  if(IdTCPClient1->Connected()) {
   //입력버퍼에 값이 있으면
   if(!IdTCPClient1->IOHandler->InputBufferIsEmpty()) {
    ilen = IdTCPClient1->IOHandler->InputBuffer->Size;
    ireadLen = ilen;
    IdTCPClient1->IOHandler->ReadBytes(readTByte,ilen);
    /////Synchronize(fn_Display);
    ireadCnt++;
   }
  }
 }
}
//#####################################################
//------------------------------------------------------------------------------
// 소켓오픈 sip:IP주소, iport:포트번호
//------------------------------------------------------------------------------
void __fastcall sockCThread::fn_SockOpen(String sip, int iport)
{
 IdTCPClient1->Host = sip;
 IdTCPClient1->Port = iport;
 if(!IdTCPClient1->Connected()) IdTCPClient1->Connect();
}
//------------------------------------------------------------------------------
// 소켓종료
//------------------------------------------------------------------------------
void __fastcall sockCThread::fn_SockClose()
{
 if(IdTCPClient1->Connected()) IdTCPClient1->Disconnect();
}
//------------------------------------------------------------------------------
// 데어터 보내기
//------------------------------------------------------------------------------
void __fastcall sockCThread::fn_SockSend(void)
{
 if(IdTCPClient1->Connected()) IdTCPClient1->IOHandler->Write(sendTByte);
}
//##########################################################
//------------------------------------------------------------------------------
// 동적 타임이벤트
//------------------------------------------------------------------------------
void __fastcall sockCThread::userOnTimer(TObject *Sender)
{
 if(IdTCPClient1->Connected()) {
  fn_SockSend();
  isendCnt++;
 }
}
//------------------------------------------------------------------------------
// sendTimer interval 설정
//------------------------------------------------------------------------------
void __fastcall sockCThread::fn_timeInterval(int msec)
{
 sendTimer->Interval = msec;
}
//------------------------------------------------------------------------------
// sendTimer Enable on/off
//------------------------------------------------------------------------------
void __fastcall sockCThread::fn_timeEnabled(bool st)
{
 sendTimer->Enabled = st;
}

그럼 위와 같이 만들어진 클래스를 사용하려면

_sockCthread.h


간단히 적자면

선어하고
sockCThread *hksSock2;

생성하고
hksSock2 = new sockCThread(this);

쓰레드 스타트
hksSock2->Start();

소켓 오픈
hksSock2->fn_SockOpen("172.16.0.192",6000);

종료는
hksSock2->fn_SockClose();
hksSock2->Terminate();
delete hksSock2;

완료해놓고 보면 정말 간단한데... ㅜ.,ㅜ;;

 

 

아! 그리구 위 _sockCthread.cpp의 헤더부분이 빠쪄있어서 뒤늦게 올립니다.

[2012.06.07추가] ^^ 그동안 너저문한 함수,변수들이 추가되었는데... 그런건 건너뛰고 보시면 될듯합니다.

_sockCthread.h

#ifndef _sockClientThreadH
#define _sockClientThreadH
//---------------------------------------------------------------------------
#include 
#include "IdTCPClient.hpp" // 이거 추가하는 걸 빠드렸었네요^^
class sockCThread : public TThread
{
private:
	int iDEV;
protected:
	void __fastcall Execute();
public:
	TIdTCPClient *IdTCPClient1;
	TTimer *sendTimer;

	void __fastcall userOnTimer(TObject *Sender);
	__fastcall ~sockCThread();

	__fastcall sockCThread(bool CreateSuspended);

	byte			sendByte[20];
	TByteDynArray	sendTByte;	//측정값 요구
	int				iTimecnt;//타임카운트 60초 1분타임용

	TByteDynArray	readTByte;

	int	isendCnt;
	int	ireadCnt;
	int ireadLen;		//읽어온 데이터 길이
	int ireadOnTest;	//ireadLen과 동일함 /ComTest에서(0으로리) 사용하기 위한 변수
	int	iTag;//소켓생성된 상태에서 장치번호를 갖으며0~19 / LEN이 분리되면 -1 상태

	// 0:측정값, 1:설정값, 2:설정변경값 이 들어왔으면
	int ireadType;

	//초기값:10, 데어터 읽어오면: 0, 데이터 요구때:++ (단 10보다크면 11로 계속 고덩)
	int	iCnt;

	int __fastcall fn_SockOpen(String sip, int iport);
	void __fastcall fn_SockClose();
	void __fastcall fn_SockSend(TByteDynArray s);

	void __fastcall fn_SockIni(int idev);

	void __fastcall fn_PTmake1(int imode);
	void __fastcall fn_PTmake2(int idev, int ino );

	void __fastcall fn_timeInterval(int msec);
	void __fastcall fn_timeEnabled(bool st);
};