[英]C# packet sent to c++ winsockets
I am just trying to send packets back and forth between my two apps but my strings aren't getting through in c++. 我只是想在两个应用程序之间来回发送数据包,但是我的字符串无法在c ++中通过。 here's what I'm doing in 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);
and here's what I got in c++ 这就是我在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);
The only value that seems to work is the packet_type which is the first one in the struct. 似乎起作用的唯一值是packet_type,它是结构中的第一个值。 that one always comes through.
那个总是来的。 What am I missing?
我想念什么?
Even though I never tried such approach, I think you cannot simply share data between 2 distinct applications using winsock, then just passing pointer. 即使我从未尝试过这种方法,我认为您也不能简单地使用Winsock在2个不同的应用程序之间共享数据,然后仅传递指针。 Memory is protected between both.
两者之间的内存均受保护。
You will need to serialize your data to a memory stream. 您将需要将数据序列化到内存流。 Using the proper classes with Encoding etc. for your strings.
对字符串使用正确的带有Encoding等的类。 Then deserialize it in your C++ app.
然后在您的C ++应用程序中反序列化它。
Try something like below for your c# application, then do the inverse in your c++, it will work. 为您的C#应用程序尝试类似下面的操作,然后在您的C ++中执行相反的操作,它将起作用。 The other way round would first read the 4 bytes, to tell how much more to read ahead for the string.... the read the string... the proceed to the next one, until an end of file marker is found.
反之,则首先读取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...
}
You have several problems: 您有几个问题:
Size
field in StructureLayout
StructureLayout
删除Size
字段 char
instead of wchar_
t, on the C# side there are Unicode strings char
而不是wchar_
t,在C#端有Unicode字符串 sizeof(Packet
) is 20. sizeof(Packet
)为20。 memcpy
copies outside the Packet struct memcpy
在Packet结构外部复制 In C++ Packet should be defined as following: 在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];
// ...
};
The problem is you pass string as pointer. 问题是您将字符串作为指针传递。 Pointer is only valid in the same process.
指针仅在同一过程中有效。 If your C# is 2.0 or above, change your struct to this:
如果您的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)
Replace ??
替换
??
with the size you want, both C# and C++ must be the SAME size. 使用所需的大小,C#和C ++的大小都必须相同。 And don't forget to add null character at the end of every string.
并且不要忘记在每个字符串的末尾添加空字符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.