C#与C++通过socket传送结构体

  • Post author:
  • Post category:其他

C#服务端:

using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;


     [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct PaketHead
        {
            public UInt32 OPCode;
            public byte DiskFlag;
            public long DiskSize;
            public long OPOffSet;
            public long OPByteCount;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            public byte[] Authentic;
            public byte Encrypt;
           public byte Ver;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            public byte[] AddIn;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] Reserve;
            public byte Zero;
            public int SizeOfHead;
        }

        protected byte[] Struct2Bytes<T>(T obj)
        {
            int size = Marshal.SizeOf(obj);
            byte[] bytes = new byte[size];
            IntPtr arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
            Marshal.StructureToPtr(obj, arrPtr, true);
            return bytes;
        }

        protected T Bytes2Struct<T>(byte[] bytes)
        {
            IntPtr arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
            return (T)Marshal.PtrToStructure(arrPtr, typeof(T));
        } 

        protected void ReadPacketHead(BinaryReader ClientReader, BinaryWriter ClientWriter)
        {
            byte[] test = null;
            test = ClientReader.ReadBytes(180);

            PaketHead Paket = Bytes2Struct<PaketHead>(test);

            Console.WriteLine(Paket.OPCode);
            Console.WriteLine(Paket.DiskFlag);
            Console.WriteLine(Paket.DiskSize);
            Console.WriteLine(Paket.OPOffSet);
            Console.WriteLine(Paket.OPByteCount);
            Console.WriteLine(System.Text.Encoding.ASCII.GetString(Paket.Authentic));
            Console.WriteLine(Paket.Encrypt);
            Console.WriteLine(Paket.Ver);
            Console.WriteLine(System.Text.Encoding.ASCII.GetString(Paket.AddIn));
            Console.WriteLine(System.Text.Encoding.ASCII.GetString(Paket.Reserve));
            Console.WriteLine(Paket.Zero);
           Console.WriteLine(Paket.SizeOfHead);
            /
            test = Struct2Bytes<PaketHead>(Paket);
            ClientWriter.Write(test);
       }

C++ Client:

 #include <winsock2.h>
 #pragma comment( lib, "ws2_32.lib" )
 
 #pragma pack(push, 1)//取消内存大小自动对齐
 
 typedef struct _PaketHead2
 {
     UINT OPCode;/
     UCHAR DiskFlag;//
     __int64 DiskSize;////
     __int64 OPOffSet;////
     __int64 OPByteCount;/////
     UCHAR    Authentic[64];//
     UCHAR    Encrypt;////
     UCHAR    Ver;
     UCHAR    AddIn[64];//
     UCHAR    Reserve[16];////
     UCHAR    Zero;///
     UINT SizeOfHead;/
 }PaketHead2,*pPaketHead2;
 
 #pragma pack(pop)
 
 //template <class T>
 //void ConvertToByteArray(T arg,unsigned char * Buffer) 
 //{
 //    for (int i=0;i<sizeof(T); i++)
 //    {
 //        int offset = i*8;
 //        Buffer[i] = (arg& (0xff << offset)) >> offset;
 //    }
 //}
 //
 //template <class T>
 //T ConvertBytesTo(byte *buf) 
 //{
 //    T ret = 0x0;
 //    for (int i=0;i<sizeof(T); i++) 
 //    {
 //        int offset = i*8;
 //        ret |= buf[i] << offset;
 //    }
 //    return (ret);
 //}
 
 int ConnTest()
 {
     SOCKET mySocket;
     WORD wVersionRequested;
    WSADATA wsaData;
    int err;
 
    wVersionRequested = MAKEWORD( 2, 2 );

    WSAStartup( wVersionRequested, &wsaData );

    try
    {
        err = WSAStartup( wVersionRequested, &wsaData );
        if ( err != 0 ) {
            printf("Couldn't find a WinSock DLL\n");
             return 1;
        }
 
         if ( LOBYTE( wsaData.wVersion ) != 2 ||
             HIBYTE( wsaData.wVersion ) != 2 ) 
         {
             printf("Couldn't find the right version for WinSock 2.2\n");
             WSACleanup( );
             return 1; 
         }
 
         SOCKADDR_IN          ServerAddr;
 
         mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
         ServerAddr.sin_family = AF_INET;
         ServerAddr.sin_port = htons(8021);    
         ServerAddr.sin_addr.s_addr = inet_addr("192.168.0.5");
 
 
         if (connect(mySocket, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr))) 
         {
           int error_code = WSAGetLastError();
            printf("Error connecting socket: %d\n",error_code);
            return 1;
        }

         /

       PaketHead2 testhead2;

        memset(&testhead2,0x00,sizeof(PaketHead2));

        testhead2.DiskFlag = 0x1;
        testhead2.OPCode = 9856;
        testhead2.DiskSize = 78954612;
        testhead2.OPOffSet = 98643217;
       testhead2.OPByteCount = 85642311;
        memcpy(testhead2.Authentic,"9876543210ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij1234567\0",64);
       memcpy(testhead2.AddIn,"9876543210ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij1234567\0",64);
        memcpy(testhead2.Reserve,"abcdefghij12345\0",16);

        testhead2.Encrypt = 0x2;
        testhead2.Ver = 0x4;
        testhead2.Zero = 0x0;
       testhead2.SizeOfHead = sizeof(PaketHead2);

        send(mySocket,(char*)(&testhead2),sizeof(PaketHead2),NULL);

       memset(&testhead2,0x00,sizeof(PaketHead2));
        recv(mySocket,(char*)(&testhead2),sizeof(PaketHead2),NULL);

        /*testhead2.Authentic[63] = 0;
        testhead2.AddIn[63] = 0;
        testhead2.Reserve[15] = 0;*/

        printf("%d\n",testhead2.OPCode);
        printf("%d\n",testhead2.DiskFlag);

        printf("%ld\n",testhead2.DiskSize);
        printf("%ld\n",testhead2.OPOffSet);
        printf("%ld\n",testhead2.OPByteCount);

        printf("%s\n",testhead2.Authentic);
        printf("%d\n",testhead2.Encrypt);
        printf("%d\n",testhead2.Ver);

       printf("%s\n",testhead2.AddIn);
        printf("%s\n",testhead2.Reserve);
        
        printf("%d\n",testhead2.Zero);

        printf("%d\n",testhead2.SizeOfHead);
        //
        closesocket(mySocket);
        WSACleanup( );
    }
    catch()
    {
        printf("Error!\n");
    }
}

引文链接:

C#与C++通过socket传送结构体

C#通过TCP传送结构体