Получаю мусор в ответе сервера по tcp client

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by blackbox, 14 Nov 2015.

  1. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    Вот кусок кода сервера, который шлет строку клиенту:

    Code:
    struct recv_packet
    {
        int magic;
        int code;
        int length;
        char *body;
    };
    char send_buff[1024+1] = "";
    ZeroMemory(&send_buff, 1024);
    memset(send_buff, 'A', 1024);
    //send_buff[1024] = '\0';
    recv_packet rcv_pkt = { 0 };
    rcv_pkt.magic = MAGIC;
    rcv_pkt.code = 0;
    rcv_pkt.length = strlen(send_buff);
    rcv_pkt.body = send_buff;
    int size = sizeof(rcv_pkt.magic) + sizeof(rcv_pkt.code) + sizeof(rcv_pkt.length) + 1024+1;
    if (send(ClientSocket, (char *)&rcv_pkt, size, 0) == SOCKET_ERROR)
    {
        printf("Error %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }

    А вот клиент на сишарпе получает данные:
    Code:
    public struct recv_packet
            {
                public int magic;
                public int code;
                public int length;
                public byte[] body;
    
            };
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                int port = 4000;
                TcpClient client = new TcpClient("127.0.0.1", 4000);
                NetworkStream nws = client.GetStream();
                BinaryWriter bw = new BinaryWriter(nws);
                BinaryReader br = new BinaryReader(nws);
                byte[] buff = new byte[512];
    
                send_packet pkt = new send_packet();
                pkt.magic = magic;
                pkt.cmd = (int)command.MOVE_MOUSE;
                while (true)
                {
    
                    bw.Write(pkt.magic);
                    bw.Write(pkt.cmd);
                  
                    //br.Read(buff, 0, 512);
                    recv_packet rcv_pkt = new recv_packet();
                    rcv_pkt.magic = br.ReadInt32();
                    rcv_pkt.code = br.ReadInt32();
                    rcv_pkt.length = br.ReadInt32();
                    rcv_pkt.body = br.ReadBytes(rcv_pkt.length);
                    string str = rcv_pkt.body.ToString();
                    //string str = System.Text.Encoding.Default.GetString(rcv_pkt.body);
                  
                    MessageBox.Show(str);
                  
                   
                }
    Только вот в rcv_pkt.body вместо 1024 штук букв А (65), первыми 12-ю байтами идет какой-то мусор. Откуда он там берется и как нормально получить данные?
     
  2. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Ошибка в том, что в коде сервера ты отправляешь не сам текст из букв "А", а указатель на буфер с этим текстом (адрес в виртуальной памяти сервера), и еще почти 1024 байта мусора, который лежит в памяти рядом со структурой rcv_pkt.

    В структуре rcv_pkt char *body нужно заменить на char send_buff[1024] и использовать этот буфер для записи в него текста.
     
  3. blackbox

    blackbox Elder - Старейшина

    Joined:
    31 Dec 2011
    Messages:
    362
    Likes Received:
    62
    Reputations:
    11
    Спасибо большое за внимание к теме. После некоторого времени вот как решил проблему:

    Code:
    char send_buff[1024+1] = "";
    ZeroMemory(&send_buff, 1025);
    memset(send_buff, 'A', 1024);
    recv_packet *rcv_pkt = (recv_packet *)malloc(sizeof(recv_packet)+1024+1);
    
    rcv_pkt->magic = MAGIC;
    rcv_pkt->code = 0;
    rcv_pkt->length = strlen(send_buff)+1;
    memcpy(rcv_pkt->body, send_buff, 1025);
    int size = sizeof(rcv_pkt->magic) + sizeof(rcv_pkt->code) + sizeof(rcv_pkt->length) + 1024 + 1;
    
    if (send(ClientSocket, (char *)rcv_pkt, size, 0) == SOCKET_ERROR)
    ...
    Теперь все данные в пакете идут подряд.