• [MFC] TCP 패킷 짤림 처리2022.11.01 PM 05:01

게시물 주소 FONT글자 작게하기 글자 키우기

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, 0sizeof(HEADER));
            memcpy(&tempHeader, msgQueue, sizeof(HEADER));
 
            if (tempHeader.OPCode == 0xAA)
            {
                if (msgQueueIndex < sizeof(MSG1))
                {    // 메시지큐에 메시지크기만큼 데이터가 없으면 처리하지 않음
                    break;
                }
 
                memset(&msg1, 0sizeof(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, 0sizeof(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, 0sizeof(MSG3));
                memcpy(&msg3, msgQueue, msgSize);        // 메시지큐에서 MSG3 내용을 뽑아냄
 
                //
                // 다이얼로그에 MSG3 전달
                //
 
                unsigned int remainMsgQueueDataSize = msgQueueIndex - msgSize;            // 수신한 메시지를 제외하고 메시지큐에 담긴 데이터의 크기
 
                memcpy(&msgQueue[0], &msgQueue[msgSize], remainMsgQueueDataSize);        // 남은 메시지큐의 데이터를 앞으로 이동
                msgQueueIndex -= msgSize;                                                // 메시지큐 인덱스 이동
            }
        }
    } while (recvSize > 0);
}
 
cs


송신쪽에서 잘 보냈더라도 수신쪽에서 한번에 못받는 경우가 있어서, 수신쪽에서 패킷합쳐주는 처리를 해줘야함 ㅇㅅㅇ

댓글 : 0 개
친구글 비밀글 댓글 쓰기

user error : Error. B.