当前位置:编程学习 > C#/ASP.NET >>

C# 用TCP/IP怎么传带指针的结构体

如题:我有一个包含指针的结构体,需要通过tcp/ip发送到客户端,但是数据没出来
结构体:
unsafe public struct Data
    {
        public char* pszData; //数据
        public int nDataLength; //数据有效长度
    }

说明:我服务器会不断往那个char*中写视频数据,目前我的做法是用下列方法先序列化为Byte[],
public byte[] serializeObjToStr(Object obj)
        {
            IFormatter formatter = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            formatter.Serialize(ms, obj);
            byte[] tmp = ms.ToArray();
            ms.Close();
            return tmp;
        }
然后客户端接收到Byte[] 后反序列化出来为结构体

问题:客户端播放不出来? 哪位大侠指点一下? --------------------编程问答-------------------- 如果用.net的序列化,就不要用指针,要用数组。.net的序列化方法只会把指针作为一个整数,而不是一个引用对象。
如果不用.net的序列化,那指针或者数组都没关系,自己为该结构体或者类写序列化方法,这个性能也更好一些,根据指针和长度直接写到buffer中就行了。 --------------------编程问答-------------------- 如果能出来真的是奇了怪了。。
所谓指针,就是一个变量。只是指向的是地址罢了。一个变量,只是四个字节(32位操作系统)。

所以你要发送的东西不能以指针的方式发送必须是有指定长度的东西。

unsafe public struct Data
    {
        public list<char> pszData;  //数据            //改为这样
        public int nDataLength;  //数据有效长度
    }

如果cs两端与传递的东西不一定都是自己写。尽量避免使用.net特有的东西。
比如序列化,这样的兼容性会好一些。结构体就是一个比较好的方法。但用结构体了变避免使用序列化。
2)结构体转byte数组:

        /// <summary>
        /// 结构体转byte数组
        /// </summary>
        /// <param name="structObj">要转换的结构体</param>
        /// <returns>转换后的byte数组</returns>
        public static byte[] StructToBytes(object structObj)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(structObj);
            //创建byte数组
            byte[] bytes = new byte[size];
            //分配结构体大小的内存空间
             IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷到分配好的内存空间
             Marshal.StructureToPtr(structObj, structPtr, false);
            //从内存空间拷到byte数组
             Marshal.Copy(structPtr, bytes, 0, size);
            //释放内存空间
             Marshal.FreeHGlobal(structPtr);
            //返回byte数组
            return bytes;
         } --------------------编程问答-------------------- public byte[] pszData;  //数据            //改为这样
list<byte>的可以使用序列化。但不建议这样用。 --------------------编程问答-------------------- 额,客户端单纯接收一个指针木有任何意义

可以考虑二进制序列化,当然客户端也必须规定相应的对象约定,才能反序列化回来

另外既然是tcp/ip 则应该考虑使用NetworkStream流传输信息

--------------------编程问答-------------------- ps:如果你是视频数据,最好不要自己生造协议规定,流媒体协议规定已经是标准协议了,自己使用已经成熟的标准协议不是更通用一些 --------------------编程问答--------------------
引用 楼主 yelangFeb 的回复:
如题:我有一个包含指针的结构体,需要通过tcp/ip发送到客户端,但是数据没出来
结构体:
unsafe public struct Data
    {
        public char* pszData; //数据
        public int nDataLength; //数据有效长度
    }

说明:我服务器会不断往那个cha……


先搞懂 pszData 下面到底是什么数据吧!(指针是为伪娘,它说明不了内部的细节)

不传数据,只“传指针”,有个屁用啊? --------------------编程问答-------------------- 首先感谢各位的回复。
确实,经过调试,数据是没有发送到客户端的。

但是关键是:如果结构中用数组,这个指针指向的数据长度每次都不一样的。 --------------------编程问答-------------------- 服务器读数据接口:private static extern int Remote_Camera2_Read(int p_hHandle, ref AVFrameData p_stAVFrameData);

客户端播放接口:private static extern int Player_InputAVFrame(int hHandle, ref AVFrameData pSTAVFrameData);

[StructLayout(LayoutKind.Sequential, Pack = 1)]
    unsafe public struct AVFrameData
    {
        public int nStreamFormat; //1表示原始流,2表示TS混合流
        public int nESStreamType; //原始流类型,1表示视频,2表示音频
        public int nEncoderType; //编码格式
        public int nCameraNo; //摄像机号,表示数据来自第几路
        public int nSequenceId; //数据帧序号
        public int nFrameType; //数据帧类型,1表示I帧, 2表示P帧, 0表示未知类型
        public int nTimeStamp; //数据采集时间戳,单位为毫秒
        public char* pszData; //数据
        public int nDataLength; //数据有效长度
        public int nFrameRate; //帧率
        public int nBitRate; //当前码率 
        public int nImageFormatId; //当前格式
        public int nImageWidth; //视频宽度
        public int nImageHeight; //视频高度
        public int nVideoSystem; //当前视频制式
        public int nFrameBufLen; //当前缓冲长度
        public int nStreamId; // 流ID
        public int nTimezone; // 时区
        public int nDaylightSavingTime; //夏令时
    }

各位大侠,哪位能提供点具体做法? --------------------编程问答-------------------- 比较直观的方法就是把
public char* pszData; //数据
public int nDataLength; //数据有效长度
这两个东西换成byte[]
方法如下
IntPtr pData = new IntPtr(pszData);
byte[] buf = new byte[nDataLen];
Marshal.Copy(pData, buf, 0, nDataLen);
//Marshal.FreeHGlobal(pData);
不知道你程序里的这个非托管内存在哪里释放的。
没有用System.Net.Sockets.Socket发送过非托管内存。 --------------------编程问答-------------------- 建议不要用unsafe机制来处理指针,去看看P/INVOKE方面的知识 --------------------编程问答-------------------- 直接用BinaryWriter往NetworkStream里写入,一个一个字段写,然后在客户用BinaryReader一个一个字段读出来,放回到结构里,不需要序列化的。 --------------------编程问答-------------------- 所以。。。。

我总是建议新手先学 c/c++

c/c++ 对于以后的编程生涯有莫大的帮助

如果楼主学了c,他就不会发这个帖了 --------------------编程问答-------------------- 传递指针有个前提,就是二边的应用程序能访问同一块内存,而楼主描述的客户端明显是访问不了服务器端的内存的,只能把指针指向的具体的数据传递过去,能传引用就怪了。 --------------------编程问答-------------------- 指针是指向内存中的一个地址。 你发给客户端他又不能用。没啥意义!
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,