/*

WSABUF.buf 를 정의를 통해 찾아보면 포인터의 형태로 되어있다고 나와있다.


비동기 수신함수 WSARecv 를 사용하는데 WSABUF를 사용하도록 하고 있다.


WSABUF는 char형과 다르게 구조체이며 안에 추가적으로 len의 길이가 들어가 있다. 


위의 내용을 가지고 의문이 드는 것은 Client 에서 동기송신 함수 send 를 이용해서 데이터를 보낼 때


서버에서는 WSABUF.buf 를 동적할당하고 길이를 늘려서 받는 것도 아니고 WSABUF 자체로 받아버린다.


그리고 읽을 때는 WSABUF.buf 를 읽으면 데이터가 또 잘 읽힌다는 것이다.



혹시 WSABUF.buf가 포인터가 아니고 배열이고 WSABUF 메모리 구조가 buf가 앞쪽에 있어서 데이터를 받을때 


그냥 뒤집어 씌워지기때문에 잘 받아지는 건가 해서 WSABUF 자체를 보내고 서버에서 WSABUF.len이 바뀌는지 보려고


1
2
3
4
5
6
7
    cin >> buf;
        strcpy(wsaBuf.buf,buf);
        wsaBuf.len = sizeof(buf);
        cout << "wsaBuf : " << wsaBuf.buf << "\n";
        cout << "wsaBuf.len : " << wsaBuf.len << "\n";
        send(sock, (char*)&wsaBuf, sizeof(wsaBuf), 0);
 
cs



이렇게 해봤는데 터졌다..  터진걸 보아하니 strcpy의  wsaBuf는 포인터가 분명했다.


WSABuf 는 자체적으로 WSARecv되어 받은 수신버퍼의 메모리를 컴퓨터에 저장하고 WSA.buf 가 그 메모리의 주소를 담는 과정을 하고 있다고 


결론내려봤다. (아닐 수도 있지만 현재는 그렇게 이해했다.)



*/


생각해보니까 WSABUF 는 소켓과 매칭 시켜놓은 버퍼와 연결시켜주는 일밖에 안한다. 그래서 포인터가 맞고 WSABuf가 가르키는 곳에 쌓는다.


신기한 점은 WSABUF.buf 에 저절로 쌓는 다는 것



구조체를 보내도 될꺼 같은데.. 하고 의문이 들어 확신하기 위해 실험 했고 성공함


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
    IOCPClass* IOCP = (IOCPClass*)pParam;
    DWORD RecvByte;
 
    ULONG_PTR upDevKey = 0;
 
    DataBox* DB = NULL;
    while (true) {
        if (GetQueuedCompletionStatus(IOCP->hIocp, &RecvByte, &upDevKey, (LPOVERLAPPED*)&DB, INFINITE) == false) {
            cout << "Get Queue Error " << endl;
            continue;
        }
        
        if (upDevKey == IOKEY_LISTEN) {
 
            CreateIoCompletionPort((HANDLE)DB->sock, IOCP->hIocp, IOKEY_CHILD, 0);
 
            cout << "New Client :  " << inet_ntoa(DB->ClientAddr.sin_addr) << "Connected.. " << endl;
 
            EnterCriticalSection(&IOCP->cs);
 
            IOCP->set.insert(DB);
 
            LeaveCriticalSection(&IOCP->cs);
        }
        else if (upDevKey == IOKEY_CHILD) {
            
            temp t;
            memset(&t, '\0'sizeof(t));
            memcpy(&t,DB->buf,sizeof(t));
            
            cout << "Client : " << inet_ntoa(DB->ClientAddr.sin_addr) << " ->> " << t.age << t.buf << endl;
 
 
        //    cout << "Client : " << inet_ntoa(DB->ClientAddr.sin_addr) << " ->> " << t.age << t.buf << endl;
 
        }
 
        DWORD Flags = 0;
        WSABUF wsaBuf;
        wsaBuf.buf = DB->buf;
        wsaBuf.len = sizeof(DB->buf);
 
        /*
            Address OR Memoey
        */
 
 
        WSARecv(DB->sock, &wsaBuf, 1NULL&Flags, DB, NULL); // Event Mapping 
 
    }
cs

서버에서 wsaBuf로 받고 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
    while (true) {
        memset(buf, '\0'200);
        cout << "Chat : ";
        char buf[200];
        cin >> buf;
 
        struct temp t;
        t.age = 10;
        strcpy(t.buf, buf);
 
        send(sock, (char*)&t, sizeof(t), 0);
    
}
    
cs

zz

클라이언트에서 age 와 char형 배열을 가지고 있는 temp라는 구조체를 보내줬음.


정상적으로 됨.

'서버프로그래밍' 카테고리의 다른 글

서버실험용 간단 클라이언트  (0) 2018.07.12
WSABUF 에 대한 실험  (0) 2018.06.27
UDP를 이용한 채팅서버 만들기  (0) 2018.06.24
내 머릿속에 남아있는 HANDlE의 의의  (0) 2018.05.27
가변길이 패킷  (0) 2018.05.27

 

 

+ Recent posts