C# Socket发送、接收结构体数组-二、Socket接收结构体数组

时间:2024-04-23 07:25:36

接收字节数组

使用已连接的Socket对象,调用其Receive方法接收数据,并存储到一个字节数组中。

Socket socket = ...; // 获取已连接的Socket对象

int receivedBytes = 0;
int totalBytesExpected = numElements * Marshal.SizeOf(typeof(ST_BonefractureInfo));
byte[] receivedBuffer = new byte[totalBytesExpected];

while (receivedBytes < totalBytesExpected)
{
    int bytesReceived = socket.Receive(receivedBuffer, receivedBytes, totalBytesExpected - receivedBytes, SocketFlags.None);
    if (bytesReceived == 0) throw new Exception("Connection closed by remote host.");
    receivedBytes += bytesReceived;
}

这里假设你知道待接收的结构体数组大小(即numElements)。在循环中,持续调用Receive方法直到接收到所有预期的数据。如果在接收过程中发现连接被远程主机关闭,抛出异常。

从字节数组还原结构体数组

使用System.Runtime.InteropServices.Marshal类提供的方法将接收到的字节数组转换回结构体数组。

ST_BonefractureInfo[] receivedBoneFractureInfos = new ST_BonefractureInfo[numElements];

IntPtr ptr = IntPtr.Zero;
try
{
    ptr = Marshal.AllocHGlobal(totalBytesExpected);

    Marshal.Copy(receivedBuffer, 0, ptr, totalBytesExpected);

    for (int i = 0; i < numElements; i++)
    {
        receivedBoneFractureInfos[i] = (ST_BonefractureInfo)Marshal.PtrToStructure(ptr + (i * Marshal.SizeOf(typeof(ST_BonefractureInfo))), typeof(ST_BonefractureInfo));
    }
}
finally
{
    if (ptr != IntPtr.Zero)
    {
        Marshal.FreeHGlobal(ptr);
    }
}

同样地,分配一段与接收到的字节数组大小相等的未托管内存,将字节数组复制到这段内存中。然后,遍历内存区域,每次从指定偏移量处将内存数据转换为对应的结构体对象,并添加到结构体数组中。 

现在,receivedBoneFractureInfos变量就包含了从Socket接收并解析得到的结构体数组。你可以进一步处理或使用这些数据了。记得处理可能出现的异常,并确保Socket的正确关闭。