현재 스레드 구조 요약

UI 스레드 (메인)
UINT CRS232SwitchLEDMonitorDlg::CommThread(LPVOID pParam)
▶생성위치
m_pThread = AfxBeginThread(CommThread, this);
▶종료 제어 변수
BOOL m_bThreadRun;
스레드 진입
CRS232SwitchLEDMonitorDlg pDlg = (CRS232SwitchLEDMonitorDlg)pParam;
=> UI객체 접근용
무한루프 구조
while(pDlg -> m_bThreadRun)
=> FALSE되면 스레드 종료
Poll 송신
pDlg -> SendPollPacket();
=> pc -> 보드
=> Led 상태 유지 + 스위치 상태 요청
응답 수신 타임슬롯 (10ms)
DWORD startTick = GetTickCount();
while(GetTickCount () - startTick < 10)
=> RS232특성
- 응답이 바로 안 올 수 있음
- 무한대기 X -> 타임 아웃 필수
ReadFile(1바이트씩)
ReadFile(pDlg -> m_hCom, &rx, 1, &dwRead, NULL)
=> 정리
송신: Poll 방식
수신: Byte Stream
종료: m_bThreadRun
블로킹: ReadFile + Sleep
안정성: 타임아웃 있음
UINT CRS232SwitchLEDMonitorDlg::UdpRecvThread(LPVOID pParam)
▶ 생성위치
m_pUdpThread = AfxBeginThread(UdpRecvThread, this);
▶ 종료 제어
BOOL m_bUdpThreadRun;
파라미터 캐스팅
CRS232SwitchLEDMonitorDlg pDlg = (CR232SwitchLEDMonitorDlg)pParam;
수신 버퍼
Byte buf[1024];
=> UDP = 패킷단위
=> 한 번 recvfrom = 한 패킷
recvfrom 블로킹
int recvlen = recvfrom(...)
=> 완전 블로킹
- 데이터 오기 전까지 대기
- CPU 낭비 없음
정상 수진
if(recvLen > 0)
UDP 수신 스레드 특징
수신방식 : 패킷단위
대기방식 : Blocking
타임아웃 : 없음
CPU 사용 : 매우적음
종료주의 : socket close필요
UINT CR232SwitchLEDMonitorDlg::UdpPollThread(LPVOID pParam)
▶ 생성 위치
m_pUdpPollThread = AfxBegin(UdpPollThread, this);
▶ 종료 제어
BOOL m_bUdpPollRun;
스레드 목적
내부 구조
while(pDlg -> m_bUdpPollRun)
{
pDlg->sendPollPacket();
Sleep(50);
}
BYTE buf[1024];
SOCKADDR_IN from;
struct sockaddr_in {
short sin_family; // AF_INET
u_short sin_port; // 송신자 포트
struct in_addr sin_addr; // 송신자 IP
};
- **보낸** 쪽 IP주소
- **보낸** 쪽 포트번호
왜??? UDP는 연결개념이 아니라 누가 보냈는지 매번 알려줘야함 -> 수신할 때 이 패킷은 누가보낸 패킷이다를 OS가 채워줌
int fromLen = sizeof(from);
recvfrom(
socket,
buf,
len,
0,
(SOCKADDR*)&from,
&fromLen
);
BYTE buf[1024]; // 데이터 받을 공간
SOCKADDR_IN from; // 송신자 정보
int fromLen = sizeof(from); // 송신자 정보 크기
UDP 수신 스레드의 핵심 루프
전체 루프 요약
int recvLen = recvfrom(
pDlg->m_udpSocket, // 1️⃣ 사용할 UDP 소켓
(char*)buf, // 2️⃣ 수신 데이터 버퍼
sizeof(buf), // 3️⃣ 최대 수신 크기
0, // 4️⃣ 옵션 (보통 0)
(SOCKADDR*)&from, // 5️⃣ 송신자 주소 저장
&fromLen // 6️⃣ 주소 구조체 크기
);
반환값 recvLen
값이 >0 : 받은 바이트 수
0: 정상적으로 받은 데이터 없음
<0: 에러
for (int i = 0; i < recvLen; i++)
packet.Add(buf[i]);
DebugPrintPacket()
pDlg->DebugPrintPacket(_T("UDP RX"), packet);
-> 수신된 UDP 패킷을 로그로 출력
ex) [UDP RX] 02 01 0E 00 02 7F 8A 03
ProcessPacket() (rs232통신할때 만든 함수)
-> 프로토콜 해석 + 실제 동작 처리
else { Sleep(1); }
언제? recvfrom 실패, 수신데이터 없을때만
전체 흐름 그림
스레드 호출
-> while(run)
-> recvfrom()
-> 데이터 있니? (1->) 아니요 -> sleep(1)
(2->) 예 -> buf=>packet복사
-> 로그출력
-> 패킷처리
바코드 부분도 똑같음