1

Тема: TCP/UDP, сервер приймає лише 4 байти або менше

Хай. Бавлюсь з сокетами, спочатку написав простенький TCP сервер та клієнт і відправляю дані, але в випадку з TCP сервер зчитував дані лише блоками по 4 байти. Тобто. якщо я відправляю "abcde", то сервер пише, що прийшло 4 байти і виводить "abcd", а потім пише, що прийшов 1 байт  і виводить "e".
Зараз я переписав це все під UDP, і тепер, якщо я відправляю пакет розміром <=4 байти, то все ок, сервер пише, що прийшло 4 або менше байтів та виводить дані, але коли я відправляю 5>= байтів, то сервер пише, що прийшло менше 0 байтів, а саме -1 байт.
Код серверу

#include <cstdio>
#include <iostream>
#include <winsock2.h>
#include <cstring>

std::string longToIp(long ip)
{
    int b[32];
    std::string fin[4];
    int it = 0;
    while (ip > 0)
    {
        int tmp = ip % 2 == 0 ? 0 : 1;
        b[it] = tmp;
        ip /= 2;

        if (it % 8 == 0 && it != 0)
        {
            int tmp1 = 0;
            for (int i = it - 8, j = 0; i < it; i++, j++)
            {
                tmp1 += pow(2, j)*b[i];
            }
            char tmp2[4];
            _itoa_s(tmp1, tmp2, 4, 10);
            fin[(int)floor(it / 8.0) - 1] = tmp2;

        }
        it++;

    }

    int tmp1 = 0;
    for (int i = 0; i < it % 8; i++)
    {
        tmp1 += pow(2, i)*b[(it - it % 8) + i];
    }

    char tmp2[4];
    _itoa_s(tmp1, tmp2, 4, 10);
    fin[3] = tmp2;

    std::string res;

    for (int i = 0; i < 4; i++)
    {
        res += fin[i];
        if (i != 3)
            res += '.';
    }

    return res;
}

int main()
{
    WSADATA WsaData;
    SOCKET sock;
    int err = WSAStartup(0x0101, &WsaData);
    if (err == SOCKET_ERROR)
    {
        printf("WSAStartup() failed: %ld\n", GetLastError());
        system("pause>>void");
        return 1;
    }

    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        std::cout << "Cannot create a socket" << std::endl;
        system("pause>>void");
        return 1;
    }

    SOCKADDR_IN sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(80);
    sin.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sock, (SOCKADDR*)&sin, sizeof(sin)) < 0)
    {
        std::cout << "Bind error: " << GetLastError() << std::endl;
        system("pause>>void");
        return 1;
    }

    int err3 = listen(sock, SOMAXCONN);

    SOCKADDR_IN from;
    int fromlen = sizeof(from);

    while (true)
    {
        char* recvBuff = new char[512];
        int n = recvfrom(sock, recvBuff, sizeof(recvBuff), 0, (sockaddr*)&from, (int*)&fromlen);
        if (n < 0)
        {
            std::cout << "Get <0 bytes: " << n << std::endl;
        }
        else
        {
            std::cout << "Received: " << n << " bytes, from ip: " << longToIp(from.sin_addr.S_un.S_addr).data()
                << "  from port: " << htons(from.sin_port) << std::endl;
            std::string str = recvBuff;
            str.resize(n);
            std::cout << str.data() << std::endl;
        }
        delete[] recvBuff;
    }

    closesocket(sock);

    system("pause>>void");
    return 0;
}

Код клієнту

#include <cstdio>
#include <iostream>
#include <winsock2.h>
#include <string>

int main()
{

    WSADATA WsaData;
    SOCKET sock;
    int err = WSAStartup(0x0101, &WsaData);
    if (err == SOCKET_ERROR)
    {
        printf("WSAStartup() failed: %ld\n", GetLastError());
        return 1;
    }

    sock = socket(AF_INET, SOCK_DGRAM, 0);

    SOCKADDR_IN anAddr;
    anAddr.sin_family = AF_INET;
    anAddr.sin_port = htons(80);
    anAddr.sin_addr.S_un.S_addr = 16777343;

    int anAddrLength = sizeof(anAddr);

    if (err == SOCKET_ERROR)
    {
        std::cout << "Connection failed: " << GetLastError() << std::endl;
    }

    while (true)
    {
        std::string str = "";
        std::getline(std::cin, str);
        std::cout << "str.length(): " << str.length() << std::endl;
        sendto(sock, str.data(), str.length(), 0, (sockaddr*)&anAddr, anAddrLength);
    }

    system("pause>>void");
}

Чому так?

2

Re: TCP/UDP, сервер приймає лише 4 байти або менше

мені вже на 2 форумі підсказали, я там просто кажу, що розмір буферу для прийняття даних == sizeof(recvBuff), а recvBuff це ж не const char[], а char*, ліл.