Profilo di Bin蜉蝣之冢FotoBlogElenchiAltro Strumenti Guida
06 gennaio

转:C#和C++结构体Socket通信

转:  C#和C++结构体Socket通信

最近在用C#做一个项目的时候,Socket发送消息的时候遇到了服务端需要接收C++结构体的二进制数据流,这个时候就需要用C#仿照C++的结构体做出一个结构来,然后将其转换成二进制流进行发送,之后将响应消息的二进制数据流转换成C#结构。

1、仿照C++结构体写出C#的结构来

Code
 1using System.Runtime.InteropServices;
 2
 3    [Serializable] // 指示可序列化
 4    [StructLayout(LayoutKind.Sequential, Pack = 1)] // 按1字节对齐
 5    public struct Operator
 6
 7{
 8         public ushort id;
 9        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] // 声明一个字符数组,大小为11
10        public char[] name;
11        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
12        public char[] pass;
13
14         public Operator(string user, string pass) // 初始化
15         {
16            this.id = 10000;
17            this.name = user.PadRight(11'\0').ToCharArray();
18            this.pass = pass.PadRight(9'\0').ToCharArray();
19        }

20    }

21
22

 

    2、注意C#与C++数据类型的对应关系

C++与C#的数据类型对应关系表
API数据类型 类型描述 C#类型 API数据类型 类型描述 C#类型
WORD 16位无符号整数 ushort CHAR 字符 char
LONG 32位无符号整数 int DWORDLONG 64位长整数 long
DWORD 32位无符号整数 uint HDC 设备描述表句柄 int
HANDLE 句柄,32位整数 int HGDIOBJ GDI对象句柄 int
UINT 32位无符号整数 uint HINSTANCE 实例句柄 int
BOOL 32位布尔型整数 bool HWM 窗口句柄 int
LPSTR 指向字符的32位指针 string HPARAM 32位消息参数 int
LPCSTR 指向常字符的32位指针 String LPARAM 32位消息参数 int
BYTE 字节 byte WPARAM 32位消息参数 int

整个结构的字节数是22bytes。

对应的C++结构体是:

 

Code
1typedef struct
2{
3     WORD id;            
4    CHAR name[11];
5    CHAR password[9];
6}
Operator;
7
8

3、发送的时候先要把结构转换成字节数组

       

Code
 1 using System.Runtime.InteropServices;     
 2
 3         /// <summary>
 4        /// 将结构转换为字节数组
 5        /// </summary>
 6        /// <param name="obj">结构对象</param>
 7        /// <returns>字节数组</returns>

 8        public byte[] StructToBytes(object obj)
 9        {
10            //得到结构体的大小
11            int size = Marshal.SizeOf(obj);
12            //创建byte数组
13            byte[] bytes = new byte[size];
14            //分配结构体大小的内存空间
15            IntPtr structPtr = Marshal.AllocHGlobal(size);
16            //将结构体拷到分配好的内存空间
17            Marshal.StructureToPtr(obj, structPtr, false);
18            //从内存空间拷到byte数组
19            Marshal.Copy(structPtr, bytes, 0, size);
20            //释放内存空间
21            Marshal.FreeHGlobal(structPtr);
22            //返回byte数组
23            return bytes;
24
25       }

26
27

接收的时候需要把字节数组转换成结构

       

Code
 1/// <summary>
 2        /// byte数组转结构
 3        /// </summary>
 4        /// <param name="bytes">byte数组</param>
 5        /// <param name="type">结构类型</param>
 6        /// <returns>转换后的结构</returns>

 7        public object BytesToStruct(byte[] bytes, Type type)
 8       {
 9            //得到结构的大小
10            int size = Marshal.SizeOf(type);
11            Log(size.ToString(), 1);
12            //byte数组长度小于结构的大小
13            if (size > bytes.Length)
14            {
15                //返回空
16                return null;
17            }

18            //分配结构大小的内存空间
19            IntPtr structPtr = Marshal.AllocHGlobal(size);
20            //将byte数组拷到分配好的内存空间
21            Marshal.Copy(bytes, 0, structPtr, size);
22            //将内存空间转换为目标结构
23            object obj = Marshal.PtrToStructure(structPtr, type);
24            //释放内存空间
25            Marshal.FreeHGlobal(structPtr);
26            //返回结构
27            return obj;
28        }

29

4、实际操作:

Code
 1using System.Collections;
 2using System.Collections.Generic;
 3using System.Net;
 4using System.Net.Sockets;
 5
 6byte[] Message = StructToBytes(new Operator("user","pass")); // 将结构转换成字节数组
 7
 8TcpClient socket = new TcpClient();
 9
10socket.Connect(ip,port);
11
12NetworkStream ns = Socket.GetStream();
13
14ns.Write(Message,0,Message.Length); // 发送
15
16byte[] Recv = new byte[1024]; // 缓冲
17
18int NumberOfRecv = 0;
19
20IList<byte> newRecv = new List<byte>();
21ns.ReadTimeout = 3000;
22try
23{
24do
25{
26// 接收响应
27NumberOfRecv = ns.Read(Recv, 0, Recv.Length);
28for (int i = 0; i < NumberOfRecv; i++)
29newRecv.Add(Recv[i]);
30}

31while (ns.DataAvailable);
32byte[] resultRecv = new byte[newRecv.Count];
33newRecv.CopyTo(resultRecv, 0);
34
35Operator MyOper = new Operator();
36
37MyOper = (Operator)BytesToStruct(resultRecv, MyOper.GetType()); // 将字节数组转换成结构

38

在这里取值的时候可能会出现只能取到一个字段,剩余的取不到的问题,怎么回事我也搞不懂,反正我的解决办法就是按照字节的顺序从resultRecv里分别取出对应的字段的字节数组,然后解码,例如:

Operator.name是11个字节,最后一位是0,Operator.id是2个字节,那么从第3位到第12位的字节就是Operator.name的内容,取出另存为一个数组MyOperName,Encoding.Default.GetString(MyOperName)就是MyOper.name的内容。

 

Code
1socket.Close();
2
3ns.Close();
4
以上是从别处转过来的,方便自己看看.特此注明!

Commenti (2)

Attendere...
Il commento immesso è troppo lungo. Immetti un commento più breve.
Immissione non effettuata. Riprova.
Impossibile aggiungere il commento al momento. Riprova più tardi.
Per aggiungere un commento è necessaria l'autorizzazione di un genitore. Chiedi autorizzazione
I tuoi genitori hanno disattivato i commenti.
Impossibile eliminare il commento al momento. Riprova più tardi.
Hai raggiunto il numero massimo di commenti pubblicabili giornalmente. Riprova tra 24 ore.
Impossibile lasciare commenti. La funzionalità è stata disattivata perché i sistemi hanno rilevato una possibile attività di spamming dal tuo account. Se ritieni che il tuo account è stato disattivato per errore, contatta il supporto tecnico di Windows Live.
Esegui il seguente controllo di protezione per completare la pubblicazione del commento.
I caratteri digitati nel controllo di protezione devono corrispondere ai caratteri dell'immagine o della riproduzione audio.

Per aggiungere un commento, accedi con il tuo Windows Live ID (se utilizzi Hotmail, Messenger o Xbox LIVE possiedi già un Windows Live ID). Accedi


Non hai ancora un Windows Live ID? Registrati

Senza nomeha scritto:
上海拉拉钢<a href="http://www.lalamo.net/Corporation_instruct.asp">膜结构公司</a>是一家专门主要从事建筑<a href="http://www.lalamo.net/">膜结构</a>上海上海宇栾钢<a href="http://www.yuluan.sh.cn/Corporation_instruct.asp">膜结构公司</a>。

上海海洋泵阀制造有限公司是专业生产<a href="http://www.sea-pump.com/dj.html">多级泵</a>,<a href="http://www.sea-pump.com/gm.html">隔膜泵</a>,<a href="http://www.sea-pump.com/hg.html">化工泵</a>,<a href="http://www.sea-pump.com/pw.html">排污泵</a>,<a href="http://www.sea-pump.com/xf.html">消防泵</a>的大型股份企业,本公司生产的消防泵,排污泵,化工泵,隔膜泵,多级泵已广泛应用于城市给排水、城市污水处理以及国家大型环保处理工程;高层建筑增压送水,园林喷灌、消防增压、远距送水、农田排灌、纺织、造纸工业排水增压以及其他工业增压配套等。产品质量稳定可靠,远销西欧,东南亚,深受广大用户信赖和好评。

上海上一泵业制造有限公司是中国最大的<a href="http://www.shangyi-pump.com/xf.html">消防泵</a>,<a href="http://www.shangyi-pump.com/pw.html">排污泵</a>,<a href="http://www.shangyi-pump.com/hg.html">化工泵</a>,<a href="http://www.shangyi-pump.com/gm.html">隔膜泵</a>,<a href="http://www.shangyi-pump.com/dj.html">多级泵</a>制造商之一,在离心历史背景制造领域,是专业生产消防泵,排污泵,化工泵,隔膜泵,多级泵、生活消防成套智能控制给水设备及水泵智能电气控制设备的大型股份制企业

全采建筑工程设计有限公司专业从事<a href="http://www.qc-design.cn">上海室内设计</a>,<a href="http://www.qc-design.cn">上海装潢设计</a>,系专业建筑室内设计机构,着力为社会提供私人住宅上海室内设计、上海装潢设计和施工服务以及公共建筑室内设计和施工服务,“全采设计”吸纳志同道合的设计师加入设计团队,其各怀绝技各有所长,从室内设计之结构、造型、色彩、材质、灯光 、配饰等各个方面给予设计团队最专业的技术支持。

E-LIKES(依莱特斯)<a href="http://www.e-likes.com/">干洗店</a>、<a href="http://www.e-likes.com/">干洗加盟</a>中心,是源自欧洲概念的先进洗涤服务终端。其清新的形象、专业的服务、专业的干洗加盟,正如其天使般的名字一样,依莱特斯干洗店深受都市人群的喜爱,欢迎加入依莱特斯干洗加盟中心<a href="http://www.shjy.sh.cn/">干洗</a>,<a href="http://www.shjy.sh.cn/ganxijiameng.html">干洗加盟

上海青浦莲盛专业生产<a href="http://www.915p.com/nijiangbeng.html">泥浆泵</a>,<a href="http://www.915p.com/xiaofangbeng.html">消防泵</a>,严格经过检验的磁力泵产品广泛应用于市政建设、农田水利、火力发电、石油化工、冶金矿山、消防环保、医药等各个领域,公司本着用心制造泥浆泵,消防泵,用情服务为宗旨愿与各界新老朋友携手共进,竭诚合作,共同创造水泵业界新的辉煌,欢迎广大新老客户前来订购泥浆泵,消防泵。

Welcome to http://www.mygamebuy.com <a href="http://www.mygamebuy.com/">Buy Wow Gold</a>, We will serve you with cheap wow gold , If you want to buy cheap wow gold, please come here , the best price and services are waiting for you Buy Wow Gold.

上海递玛吉传动机械有限公司是专业开发减速器、销售减速器的厂家, 公司以现代化网络平台和呼叫中心为服务核心,为用户提供高品质的减速器产品与服务保障,
<a href="http://www.dimaji.com/jsdj.asp">减速电机</a>,<a href="http://www.dimaji.com/cljsj.asp">齿轮减速机</a>,<a href="http://www.dimaji.com/bxzljsj.asp">摆线针轮减速机</a>,<a href="http://www.dimaji.com/wlwgjsj.asp">蜗轮蜗杆减速机</a>,<a href="http://www.dimaji.com/wljsj.asp">蜗轮减速机</a>,<a href="http://www.dimaji.com">减速器</a>,<a href="http://www.dimaji.com/jsdj.asp">sew减速机</a>

上海岭秦数码科技有限公司成立于1998年,销售各类智能卡(会员卡,<a href="http://www.200100.net/">贵宾卡</a>,IC卡,<a href="http://www.200100.net/">PVC卡</a>,<a href="http://www.200100.net/">IC卡</a>)及其设备的高科技企业。

上海韩昶钢板有限公司主营宝钢、武钢、鞍本钢镀锌板卷以及彩涂卷等<a href="http://www.shhanchang.com/product.asp?d_id=3">楼承板</a>,<a href="http://www.shhanchang.com/">C型钢</a>,<a href="http://www.shhanchang.com/">镀锌卷</a>,量大从优,公司有数控剪切设备,可按客户要求剪切、加工各种镀锌、冷轧卷及特殊规格。加工费30元/吨及镀锌卷,C型钢,楼承板加工制作,欢迎广大新老客户前来洽谈.

上海舒创模型广告制作有限公司,是美国Creator Models 直接领导下的企业,是国内最具创新力的专业<a href="http://www.shuchuang.sh.cn">上海模型</a>,<a href="http://www.shuchuang.sh.cn/cb.html">船舶模型</a>,<a href="http://www.shuchuang.sh.cn/jx.html">机械模型</a>,<a href="http://www.shuchuang.sh.cn/gy.html">工业模型</a>公司,在不断发展的趋势下,我们为全国各大设计研究院,制造厂商,博物馆,企业展厅,军区,职业技能学校, 房产开发商,品牌专卖店及其他事业单位制作了大量的上<a href="http://www.shxiandao.cn/">涡流探伤</a>。
9 Mag.
水泽ha scritto:
天书 ······
6 Gen.

Riferimenti

L'URL di riferimento per questo intervento è:
http://halberdier.spaces.live.com/blog/cns!3DA54C2517D89387!493.trak
Blog che fanno riferimento a questo intervento
  • Nessuno