C# 数据包发送到 c++ winsockets

标签 c# c++ sockets marshalling winsock

我只是想在我的两个应用程序之间来回发送数据包,但我的字符串在 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 个不同的应用程序之间共享数据,然后只传递指针。内存在两者之间受到保护。

您需要将数据序列化为内存流。将适当的类与编码等一起用于您的字符串。然后在您的 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...
        }

关于C# 数据包发送到 c++ winsockets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23166974/

相关文章:

c# - 假序列化信息

c# - C++ 到 C#,static_cast 到枚举

c++ - 如何获取接口(interface) getaddrinfo() (addrinfo) 用于 connect() 的 IP

linux - 判断socket上是否还有Data残留并丢弃

javascript - 保存每个客户端的 socket.io 数据

c# - 如何使用 Windows 窗体应用程序检索 ComboBox 中的数据库表?

C# XNA 鼠标位置

c++ - 视觉 C++ : InvokeHelper() function

C++如何替换一个函数但仍然使用原来的函数?

c# - 没有这样的主机是已知的套接字连接