[英]C# packet sent to c++ winsockets
我只是想在兩個應用程序之間來回發送數據包,但是我的字符串無法在c ++中通過。 這就是我在C#中所做的
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Size=32)]
public struct Packet
{
public uint packet_type;
[MarshalAs(UnmanagedType.LPWStr, SizeConst = 8)]
public string file_name;
[MarshalAs(UnmanagedType.LPWStr, SizeConst = 8)]
public string template_name;
[MarshalAs(UnmanagedType.LPWStr, SizeConst = 8)]
public string file_name_list;
[MarshalAs(UnmanagedType.LPWStr, SizeConst = 8)]
public string file_buffer;
}
var data = new Packet
{
packet_type = (uint)action,
file_name = fileName + Char.MinValue,
file_name_list = "" + Char.MinValue,
template_name = "" + Char.MinValue
};
byte[] buffer = new byte[Marshal.SizeOf(typeof(Packet))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(data, handle.AddrOfPinnedObject(), false);
handle.Free();
var bytesSent = _client.Client.Send(buffer);
byte[] buffer = new byte[Marshal.SizeOf(typeof(Packet))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(data, handle.AddrOfPinnedObject(), false);
handle.Free();
var bytesSent = _client.Client.Send(buffer);
這就是我在C ++中得到的
struct Packet {
unsigned int packet_type;
char* file_name;
char* template_name;
char* file_name_list;
char* file_data;
void serialize(char * data) {
memcpy(data, this, sizeof(Packet));
}
void deserialize(char * data) {
memcpy(this, data, sizeof(Packet));
}
};
char network_data[MAX_PACKET_SIZE];
recv(curSocket, buffer, MAX_PACKET_SIZE, 0);
似乎起作用的唯一值是packet_type,它是結構中的第一個值。 那個總是來的。 我想念什么?
即使我從未嘗試過這種方法,我認為您也不能簡單地使用Winsock在2個不同的應用程序之間共享數據,然后僅傳遞指針。 兩者之間的內存均受保護。
您將需要將數據序列化到內存流。 對字符串使用正確的帶有Encoding等的類。 然后在您的C ++應用程序中反序列化它。
為您的C#應用程序嘗試類似下面的操作,然后在您的C ++中執行相反的操作,它將起作用。 反之,則首先讀取4個字節,以告訴該字符串要讀取的字節數更多。...讀取的字符串...繼續進行下一個字節,直到找到文件標記的末尾。
string myString = "abc";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(myString);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(BitConverter.GetBytes(buffer.Length), 0, 4);
ms.Write(buffer, 0, buffer.Length);
//... rest of code...
}
您有幾個問題:
StructureLayout
刪除Size
字段 char
而不是wchar_
t,在C#端有Unicode字符串 sizeof(Packet
)為20。 memcpy
在Packet結構外部復制 在C ++中,數據包應定義如下:
struct Packet {
unsigned int packet_type;
wchar_t file_name[8];
wchar_t template_name[8];
wchar_t file_name_list[8];
wchar_t file_data[8];
// ...
};
問題是您將字符串作為指針傳遞。 指針僅在同一過程中有效。 如果您的C#為2.0或更高版本,請將您的結構更改為此:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct Packet
{
public uint packet_type;
public fixed char file_name[??];
public fixed char template_name[??];
public fixed char file_name_list[??];
public fixed char file_buffer[??];
}
#pragma pack(push, 1)
struct Packet {
unsigned int packet_type;
wchar_t file_name[??];
wchar_t template_name[??];
wchar_t file_name_list[??];
wchar_t file_data[??];
void serialize(char * data) {
memcpy(data, this, sizeof(Packet));
}
void deserialize(char * data) {
memcpy(this, data, sizeof(Packet));
}
};
#pragma pack(pop)
替換??
使用所需的大小,C#和C ++的大小都必須相同。 並且不要忘記在每個字符串的末尾添加空字符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.