c++和C#的通讯问题,
代码如下,C++结构体的数据如下
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.IO;
namespace ConsoleServer
{
class Server
{
static void Main(string[] args)
{
Console.WriteLine("Server Running……");
IPAddress m_ipaddress = IPAddress.Parse("127.0.0.1");
int m_port = Convert.ToInt32(8088);
IPEndPoint m_ipep = new IPEndPoint(m_ipaddress, m_port);
TcpListener m_tcplistener = new TcpListener(m_ipep);
m_tcplistener.Start();
Console.WriteLine("Server Listening……");
while (true)
{
TcpClient m_tcpclient = m_tcplistener.AcceptTcpClient();
ServerSocket m_serversocket = new ServerSocket(m_tcpclient);
}
}
}
public class ServerSocket
{
private TcpClient m_tcpclient;
private NetworkStream m_networkstream;
private const int m_buffersize = 8192;
private byte[] m_buffer;
private StructHandler m_structhandler;
public ServerSocket(TcpClient _tcpclient)
{
this.m_tcpclient = _tcpclient;
Console.WriteLine("Client Connectting: {0} <-- {1}", m_tcpclient.Client.LocalEndPoint, m_tcpclient.Client.RemoteEndPoint);
this.m_networkstream = _tcpclient.GetStream();
this.m_buffer = new byte[m_buffersize];
this.m_structhandler = new StructHandler();
AsyncCallback m_asynccallback = new AsyncCallback(StepAsyncCallback);
m_networkstream.BeginRead(m_buffer, 0, m_buffersize, m_asynccallback, null);
}
private void StepAsyncCallback(IAsyncResult _asyn)
{
try
{
int m_bytes = 0;
lock (m_networkstream)
{
//获取数据包字节数
m_bytes = m_networkstream.EndRead(_asyn);
Console.WriteLine("Reading Client Data: {0} bytes", m_bytes);
}
if (m_bytes == 0) throw new Exception("读取到0字节");
//解析数据包内容
string m_msg = Encoding.Unicode.GetString(m_buffer, 0, m_bytes);
//获取数据包
byte[] m_packet = Encoding.Unicode.GetBytes(m_msg);
//转换数据格式
StructHandler.ResponseLogin m_socketpaket = Bytes2Struct <StructHandler.ResponseLogin>(m_packet);
Console.WriteLine(m_socketpaket.Id);
Console.WriteLine(Encoding.ASCII.GetBytes(m_socketpaket.Account));
Console.WriteLine(Encoding.ASCII.GetBytes(m_socketpaket.Password));
//转换数据格式
m_packet = Struct2Bytes <StructHandler.ResponseLogin>(m_socketpaket);
//写出数据
m_networkstream.Write(m_packet, 0, m_packet.Length);
m_networkstream.Flush();
Console.WriteLine("发送数据包: {0}", m_packet);
// 无限循环调用BeginRead()
lock (m_networkstream)
{
AsyncCallback m_AsyncCallback = new AsyncCallback(StepAsyncCallback);
m_networkstream.BeginRead(m_buffer, 0, m_buffersize, m_AsyncCallback, null);
}
}
catch (Exception ex)
{
if (m_networkstream != null)
{
m_networkstream.Dispose();
}
m_tcpclient.Close();
Console.WriteLine(ex.Message);
}
}
private 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;
}
private T Bytes2Struct <T>(byte[] bytes)
{
IntPtr arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
return (T)Marshal.PtrToStructure(arrPtr, typeof(T));
}
}
public class StructHandler
{
[Serializable]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ResponseLogin
{
public long Id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public char[] Account;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public char[] Password;
public ResponseLogin(string _account, string _password)
{
this.Id = 10000;
this.Account = _account.PadRight(20, '\0').ToCharArray();
this.Password = _password.PadRight(50, '\0').ToCharArray();
}
}
public enum ProtocolID
{
}
[Serializable]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PackHead
{
}
[Serializable]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PackBody
{
PackHead Head;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
char[] PackData;
byte StateData;
}
public struct ClientMessage
{
ProtocolID Pid;
PackBody MsgBody;
}
}
}
------解决方案--------------------
很久没用过C#了。这帖子发在C#版比较好。