[英]How to Send C++ Struct Message from C# Socket?
這是我需要從 C# 傳遞的 C++ 消息:
struct LoginMessage:public NMessage { char szUser[ 16 ]; char szPass[ 16 ]; LoginMessage() { msgId = CTRL_SESSION_LOGIN; msgSize = sizeof( LoginMessage ); } }; struct NMessage { DWORD msgSize; union { DWORD msgId; struct { BYTE msgId0; BYTE msgId1; BYTE msgId2; BYTE msgId3; }; }; NMessage() { } BOOL IsLegal() { return msgSize>=sizeof(NMessage) && msgSize
C# 中的這個等價物是什么,以便 C++ 可以理解這個消息? 示例代碼非常感謝。
回答我自己的問題..
[StructLayout(LayoutKind.Sequential)]
public struct LoginMessage
{
public int msgSize;
public int msgId;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
public string szUser;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
public string szPass;
}
重要的是要注意 class 屬性的順序,以便發送到 c++ 的字節數組與預期的完全相同。
看看這個。 這是一個很好的編組指南。
看看 MSDN 上的StructLayout屬性。 該頁面上有一個很好的示例,說明如何創建可以正確編組的結構。 您還可以查看http://www.pinvoke.net以查看如何將 Windows API 結構定義為編組的不同示例。 正確定義結構后,您應該能夠使用Marshal.StructureToPtr或Marshal.PtrToStructure 。 這是一篇關於它的簡短文章: http://geekswithblogs.net/taylorrich/archive/2006/08/21/88665.aspx
我通常使用類似的方法手動序列化數據。
class NMessage {
byte[] buffer;
//ctor to create a new message for sending.
public NMessage(int nSize) {
buffer = new byte[nSize];
Buffer.BlockCopy(BitConverter.GetBytes(nSize), 0, buffer, 0, sizeof(UInt32));
}
//ctor to create msg from received data.
publix NMessage(byte[] buffer) {
this.buffer = buffer;
}
public UInt32 MessageId {
get { return BitConverter.ToUInt32(buffer, 4);
set { Buffer.BlockCopy(BitConverter.GetBytes(value), 0, buffer, 4, sizeof(UInt32)); }
}
...
public Byte MessageId2 {
get { return buffer[6]; }
set { buffer[6] = value; }
}
...
public UInt32 Size {
get { return BitConverter.ToUInt32(buffer, 0) }
}
public Byte[] Buffer {
get { return buffer; }
}
}
class LoginMessage : NMessage {
Encoding encoding = new ASCIIEncoding(); //or whatever encoding you need.
public LoginMessage() : base(16 + 16) {
this.MessageId = CTRL_SESSION_LOGIN;
}
public LoginMessage(NMessage message) : base(message.Buffer) {
}
public string User {
get { return encoding.GetString(buffer, 8, 16); }
set { Buffer.BlockCopy(encoding.GetBytes(value), 0, buffer, 8, 16);
}
public string Pass {
get { return encoding.GetString(buffer, 24, 16); }
set { Buffer.BlockCopy(encoding.GetBytes(value), 0, buffer, 24, 16);
}
}
因此,您只需創建新消息,設置它的數據,然后發送 Buffer 屬性。
Send((new LoginMessage {
User = "user",
Pass = "pass",
}).Buffer);
在接收端,如果你有足夠的數據,你可以從你收到的 byte[] 構建消息。
byte[] recvBuf = new byte[MAX_RECV];
int recvSize = Receive(recvBuf);
...
var message = new NMessage(recvBuf);
if (message.MessageId == CTRL_SESSION_LOGIN)
var login = new LoginMessage(message);
var user = login.User;
...
無論如何,這只是一個粗略的概述,代碼顯然需要清理,因為我將其簡化為僅演示這個想法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.