|
안녕하세요?
send함수에 구조체를 포인터로 넘기셨네요.
그런데 writefile에서는 sizeof( (char *)&tempPacket)로 보낼 크기를 정하셨구요.
sizeof연산자는 포인터의 크기(4바이트)를 반환하니까 구조체의 앞쪽 4바이트만 전송할껍니다.
그럼 받는쪽에서는 당연히 깨진 구조체를 받는거죠.
_PACKET 구조체의 멤버중에 포인터변수가 없다면 sizeof(_PACKET)하시면 정확한 크기를 구합니다.
안에 만약 포인터변수가 있고 힙을 가르키고 있다면 직접 크기를 지정해 주셔야 합니다.
그럼 이만...
ps>
포인터 케스트를 이용해서 바로 전송하지 마시고 님께서 직접 문자열로 바꾼 다음(endian을 맞추는것까지 포함해서요) 전송하시는 것을 권하고 싶습니다. serialize...
구리구리 님이 쓰신 글 :
: // 단순히 문자만 주고 받을때는 이렇게 해도 잘 돌아갔습니다
: void __fastcall TMESSENGER_SERVER::SendAll( _PACKET *tempPacket )
: {
: CXOverlapped *pSendPacket = new CXOverlapped;
:
: // 둘다 char형 배열입니다
: strcpy( pSendPacket->szRecv, tempPacket->cNameMsg );
:
: pSendPacket->mode = WRITE;
: pSendPacket->iNum = 0;
: for( int i = 0; i < g_nClients; i++ )
: {
: int len = strlen( pSendPacket->szRecv );
: pSendPacket->szRecv[len+1] = '\0';
:
: if( INVALID_SOCKET == g_asockClients[i] )
: continue;
:
:
: // char형 배열을 전송하고
: if( FALSE == WriteFile( (HANDLE)g_asockClients[i],
: pSendPacket->szRecv,
: len,
: NULL,
: pSendPacket ) )
: {
: if( GetLastError() != ERROR_IO_PENDING )
: {
: MESSENGER_SERVER->ListBox1->Items->Add("WSARecv() failed with error");
: return;
: }
: }
: pSendPacket->iNum++;
: }
: }
:
:
:
:
:
: unsigned int __stdcall RecvMsg(void *arg)
: {
: SOCKET sock = (SOCKET)arg;
: char nameMessage[NAMESIZE + BUFSIZE];
: int strLen;
:
: while ( 1 )
: {
: // char형으로 받았을때는 잘나옵니다
: strLen = recv( sock, nameMessage, NAMESIZE + BUFSIZE - 1, 0 );
:
: if (strLen == -1 )
: return 1;
: nameMessage[strLen] = '\0';
: AppMain->WriteStatusMsgDlg(nameMessage);
: }
: }
:
:
:
: /////////////////////////////////////////////////////////////////////////////////////////////////////서버에서 클라이언트로 패킷 클래스를 보내서 iMessageFlag, cNameMsg값을 출력하면 이상한 값이 나오네요
:
: void __fastcall TMESSENGER_SERVER::SendAll( _PACKET *tempPacket )
: {
: CXOverlapped *pSendPacket = new CXOverlapped;
:
: // 값이 제대로 나오는지 보기위해 클라이언트로 전송하기전에
: // 서버에서 한번 찍어봤음. 값은 제대로 나옵니다
: MESSENGER_SERVER->ListBox1->Items->Add( tempPacket->iMessageFlag );
: MESSENGER_SERVER->ListBox1->Items->Add( tempPacket->cNameMsg );
:
: pSendPacket->mode = WRITE;
: pSendPacket->iNum = 0;
: for( int i = 0; i < g_nClients; i++ )
: {
: if( INVALID_SOCKET == g_asockClients[i] )
: continue;
:
: // 패킷으로 보내고
: if( FALSE == WriteFile( (HANDLE)g_asockClients[i],
: (char *)&tempPacket,
: sizeof( (char *)&tempPacket ),
: NULL,
: pSendPacket ) )
: {
: if( GetLastError() != ERROR_IO_PENDING )
: {
: MESSENGER_SERVER->ListBox1->Items->Add("WSARecv() failed with error");
: return;
: }
: }
: pSendPacket->iNum++;
: }
: }
:
:
:
: unsigned int __stdcall RecvMsg(void *arg)
: {
: SOCKET sock = (SOCKET)arg;
: char nameMessage[MY_COMMUICATION_BUFFER];
: int strLen;
:
: while ( 1 )
: {
: // 문자열로 받아서
: strLen = recv( sock, nameMessage, MY_COMMUICATION_BUFFER, 0 );
:
: if (strLen == -1 )
: return 1;
:
: // 값을 패킷 클래스에 넣고
: _PACKET *MyPacket = (_PACKET *)nameMessage;
:
: // 값이 제대로 나오는지 확인하려고 다 찍어봤음...
: AppMain->WriteStatusMsgDlg( nameMessage );
: AppMain->WriteStatusMsgDlg( MyPacket->cNameMsg );
: AppMain->WriteStatusMsgDlg( MyPacket->iMessageFlag );
: }
: }
|