Конвертировать данные, отправленные с сервера C, используя BinaryFormatter в C # - PullRequest
0 голосов
/ 28 сентября 2019

Я пытаюсь общаться, используя C и C #.Это код, который отправляет структуру с сервера C ++, который клиент получает, интерпретирует и отправляет обратно на сервер C.

Я пытался преобразовать в тип int с помощью BinaryFormatter в частикод, в котором я закрыл его как комментарий, но получаю исключение.

Исключение: необработанное Исключение: 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();
        }
    }
}

  • Добавить

Я просто преобразовал его в байтовый массив, используя BinaryFormatter в C #.Это результат.

int в байтовый массив -> 159,134,1,0,

Преобразовать int в байтовый массив с помощью BinaryFormatter -> 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?

1 Ответ

1 голос
/ 29 сентября 2019

BinaryFormatter сериализует «граф объекта», который представляет собой данные с информацией о типе.

BinaryReader - это класс, который вы можете искать.

...