c# - 在 C# 中使用 BinaryFormatter 转换从 C 服务器发送的数据
问题描述
我正在尝试使用 C 和 C# 进行通信。这是从 C++ 服务器发送结构的代码,客户端接收、解释并发送回 C 服务器。
我尝试在将其作为注释关闭的代码部分中使用 BinaryFormatter 转换为 int 类型,但出现异常。
异常:未处理的异常:System.Runtime.Serialization.SerializationException:在解析完成之前到达流的结尾。
所以我被迫使用BitConverter,但BitConverter只能转换为固定类型。
如果这不起作用,我将无法发送和接收结构。这个问题有解决方案吗?
[C服务器]
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32")
#define PORT 4567
void err_exit(const char* msg) {
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
0, WSAGetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&lpMsgBuf, 0, 0);
MessageBox(NULL, (LPCSTR)lpMsgBuf, msg, MB_OK);
LocalFree(lpMsgBuf);
exit(1);
}
int recvn(SOCKET sock, char* buffer, int length, int flags) {
int curLen = 0;
while (curLen < length) {
int recvLen = recv(sock, buffer, length, flags);
if (recvLen < 1)
return SOCKET_ERROR;
buffer += recvLen;
curLen += recvLen;
}
return curLen;
}
int main(int argc, char* argv[]) {
printf("c server\n");
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
SOCKET gate = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (gate == INVALID_SOCKET)err_exit("gate");
SOCKADDR_IN gateAddress = { 0, };
gateAddress.sin_family = AF_INET;
gateAddress.sin_addr.s_addr = htonl(INADDR_ANY);
gateAddress.sin_port = htons(PORT);
if (bind(gate, (const sockaddr*)&gateAddress, sizeof(gateAddress)) == SOCKET_ERROR)err_exit("bind");
if (listen(gate, SOMAXCONN) == SOCKET_ERROR)err_exit("listen");
SOCKADDR_IN clientAddress = { 0, };
int cliAddrSize = sizeof(clientAddress);
SOCKET client = accept(gate, (sockaddr*)&clientAddress, &cliAddrSize);
int sendNum = 99999;
int sendLen = send(client, (char*)&sendNum, sizeof(int), 0);
printf("send: %d\n", sendNum);
int recvNum = 0;
int recvLen = recvn(client, (char*)&recvNum, sizeof(int), 0);
printf("recv: %d\n", recvNum);
closesocket(client);
closesocket(gate);
WSACleanup();
system("pause");
}
[C#客户端]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.InteropServices;
using System.Net;
using System.Net.Sockets;
namespace Client
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("C# client");
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
sock.Connect(iPEndPoint);
int recvNum = 0;
byte[] recvBuf = new byte[sizeof(int)];
sock.Receive(recvBuf);
recvNum = BitConverter.ToInt32(recvBuf, 0);
Console.WriteLine("recv: " + recvNum);
// Here is error.
// Unhandled Exception:
// System.Runtime.Serialization.SerializationException:
// End of stream reached before parsing completed.
/*
using (MemoryStream ms = new MemoryStream(recvBuf))
{
BinaryFormatter bf = new BinaryFormatter();
recvNum = (int)bf.Deserialize(ms);
}
//*/
sock.Send(recvBuf);
Console.WriteLine("send: " + recvNum);
sock.Close();
}
}
}
- 添加
我只是在 C# 中使用 BinaryFormatter 将它转换为字节数组。这就是结果。
int 到字节数组 -> 159,134,1,0,
使用 BinaryFormatter 将 int 转换为字节数组 -> 0,1,0,0,0,255,255,255,255,1,0,0,0,0,0,0,0,4,1,0,0,0,12,83,121,115,116,101,109,46 ,73,110,116,51,50,1,0,0,0,7,109,95,118,97,108,117,101,0,8, 159,134,1,0 ,11,
BinaryFormatter 似乎在字节的开头和数据的结尾存储了不同的信息。
我应该使用 BinaryFormatter 以外的东西吗?
解决方案
BinaryFormatter 序列化“对象图”,它是具有类型信息的数据。
BinaryReader是您可能正在寻找的类。
推荐阅读
- python - 在 kivy 应用程序中列出数据库中的所有名称
- php - 当我使用路径时,symfony id 加 1
- google-apps-script - 根据值自动排序工作表
- kotlin - 最少 2 个可为空的数字
- javascript - 我得到 Uncaught Syntax Error: Unexpected identifier on VSCODE (NodeJS)
- gitlab-ci - Gitlab CI:使用变量时,带有axios调用的api触发器不起作用
- intellij-idea - 如何使用 IntelliJ IDEA 共享 (VCS) 运行配置模板
- google-api - Youtube Api 没有结果问题
- python - 删除字符串,无论 Python 中的大小写如何
- ios - 如何使用 swift 从 PKCS#12 文件中提取证书和私钥 PEM 字符串