msg.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #pragma once typedef struct stHeader { unsigned char StartCode; unsigned char SenderID; unsigned char ReceiverID; unsigned char OPCode; unsigned short DUTID; unsigned short Reserved; unsigned short Size; // 헤더를 제외한 메시지 크기(byte) unsigned short SeqNo; unsigned int ProcedureType; }HEADER; // 16Byte typedef struct stMsg1 { HEADER header; unsigned int Data1; }MSG1; typedef struct stMsg2 { HEADER header; unsigned int Data1; unsigned int Data2; }MSG2; typedef struct stMsg3 // 가변길이 메시지 { HEADER header; unsigned int Data[20]; // 최대 20개 데이터 전달, 1개만 올 수도 있음. // 정의는 최대크기로 해놓고 수신한 크기만큼 memcpy() }MSG3; | cs |
메시지 수신부
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #pragma once #include <WinSock2.h> #include "msg.h" #pragma comment(lib, "Ws2_32.lib") // // TCP 패킷 짤림 처리 (고정 길이 메시지, 가변 길이 메시지) // void Receive() { MSG1 msg1; // 수신메시지1 MSG2 msg2; // 수신메시지2 MSG3 msg3; // 수신메시지3, 가변길이 메시지 SOCKET socket; // 수신소켓 int recvSize = 0; // recv() 반환값 const unsigned int buffSize = 255; // TCP 수신 버퍼 크기 unsigned char buff[buffSize]; // TCP 수신 버퍼 const unsigned int msgQueueSize = buffSize * 4; // 메시지큐 크기 unsigned char msgQueue[msgQueueSize]; // 메시지큐, TCP 수신 버퍼 저장 unsigned int msgQueueIndex = 0; // 메시지큐 현재 위치 memset(msgQueue, 0, msgQueueSize); do { memset(buff, 0, buffSize); recvSize = recv(socket, (char*)buff, buffSize, 0); // TCP 메시지 수신 memcpy(&msgQueue[msgQueueIndex], buff, recvSize); // 수신한 데이터를 메시지큐로 옮김 msgQueueIndex += recvSize; // 메시지큐 위치 이동 while (msgQueueIndex > sizeof(HEADER)) { HEADER tempHeader; memset(&tempHeader, 0, sizeof(HEADER)); memcpy(&tempHeader, msgQueue, sizeof(HEADER)); if (tempHeader.OPCode == 0xAA) { if (msgQueueIndex < sizeof(MSG1)) { // 메시지큐에 메시지크기만큼 데이터가 없으면 처리하지 않음 break; } memset(&msg1, 0, sizeof(MSG1)); memcpy(&msg1, msgQueue, sizeof(MSG1)); // 메시지큐에서 MSG1 내용을 뽑아냄 // // 다이얼로그에 MSG1 전달 // unsigned int remainMsgQueueDataSize = msgQueueIndex - sizeof(MSG1); // 수신한 메시지를 제외하고 메시지큐에 담긴 데이터의 크기 memcpy(&msgQueue[0], &msgQueue[sizeof(MSG1)], remainMsgQueueDataSize); // 남은 메시지큐의 데이터를 앞으로 이동 msgQueueIndex -= sizeof(MSG1); // 메시지큐 인덱스 이동 } else if (tempHeader.OPCode == 0xBB) { if (msgQueueIndex < sizeof(MSG2)) { // 메시지큐에 메시지크기만큼 데이터가 없으면 처리하지 않음 break; } memset(&msg2, 0, sizeof(MSG2)); memcpy(&msg2, msgQueue, sizeof(MSG2)); // 메시지큐에서 MSG2 내용을 뽑아냄 // // 다이얼로그에 MSG2 전달 // unsigned int remainMsgQueueDataSize = msgQueueIndex - sizeof(MSG2); // 수신한 메시지를 제외하고 메시지큐에 담긴 데이터의 크기 memcpy(&msgQueue[0], &msgQueue[sizeof(MSG2)], remainMsgQueueDataSize); // 남은 메시지큐의 데이터를 앞으로 이동 msgQueueIndex -= sizeof(MSG2); // 메시지큐 인덱스 이동 } else if (tempHeader.OPCode == 0xCC) { unsigned int msgSize = sizeof(HEADER) + tempHeader.Size; // 가변 메시지의 크기 if (msgQueueIndex < msgSize) { // 메시지큐에 메시지크기만큼 데이터가 없으면 처리하지 않음 break; } memset(&msg3, 0, sizeof(MSG3)); memcpy(&msg3, msgQueue, msgSize); // 메시지큐에서 MSG3 내용을 뽑아냄 // // 다이얼로그에 MSG3 전달 // unsigned int remainMsgQueueDataSize = msgQueueIndex - msgSize; // 수신한 메시지를 제외하고 메시지큐에 담긴 데이터의 크기 memcpy(&msgQueue[0], &msgQueue[msgSize], remainMsgQueueDataSize); // 남은 메시지큐의 데이터를 앞으로 이동 msgQueueIndex -= msgSize; // 메시지큐 인덱스 이동 } } } while (recvSize > 0); } | cs |
송신쪽에서 잘 보냈더라도 수신쪽에서 한번에 못받는 경우가 있어서, 수신쪽에서 패킷합쳐주는 처리를 해줘야함 ㅇㅅㅇ