niten_d0raku
@niten_d0raku

Почему теряется часть массива символов при его передаче по сокету?

клиент
#include <winsock2.h>
#include <iostream>
#include <thread>

#pragma warning(disable: 4996)

SOCKET s;
char connectId[10];

void toMail(char* buf) {
    
}

void updateServ() {
    while (true) {
        Sleep(1);
        send(s, " ", sizeof(" "), 0); 
    }
}

void receiv228() {
    char buf[20000];
    memset(buf, 0, sizeof(buf));
    while (recv(s, buf, sizeof(buf), 0) > 0) {
        std::cout << buf << "\n";                  // 2 mail 1
        memset(buf, 0, sizeof(buf));
    }
}

int main()
{
    setlocale(LC_ALL, "");
    WSADATA ws;
    WSAStartup(MAKEWORD(2, 2), &ws);
    
    s = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(1234);
    char buf[20000];
    memset(buf, 0, sizeof(buf));                                                 

    connect(s, (sockaddr*)&server_addr, sizeof(server_addr));
    recv(s, connectId, sizeof(connectId), 0);
    std::cout << "Соединение №" << connectId << "\n";

    std::thread update(updateServ);
    std::thread receiv(receiv228);
    while (1) {
        std::cout << "message: ";
        std::cin.getline(buf, 20000); // 2 mail 1 privet!
        send(s, buf, sizeof(buf), 0); 
        memset(buf, 0, sizeof(buf));
    }
}


сервер
#include <WinSock2.h>
#include <iostream>
#include <vector>
#include <thread>

#pragma warning(disable:4996)

SOCKET s;
std::vector<SOCKET> client_sockv;
std::vector<SOCKADDR_IN> client_addrv;

void msgProc(char buf[20000]) { // "номер, вид, адресат, сообщение"
    buf[19999] = '\n';
    char number[10];
    char type[10];
    char recipient[10];
    char msg[19993];
    memset(number, 0, sizeof(number));
    memset(type, 0, sizeof(type));
    memset(recipient, 0, sizeof(recipient));
    memset(msg, 0, sizeof(msg));
    int i = 0;
    int count = 0;
    for (; (buf[i] != ' ') && (i < 10); i++) {
        number[i] = buf[i];
        count++;
    }
    i++;
    int countsave = count;
    for (; (buf[i] != ' ') && (i < 10); i++) {
        type[i-countsave-1] = buf[i];
        count++;
    }
    i++;
    countsave = count;
    for (; (buf[i] != ' ') && (i < 10); i++) {
        recipient[i - countsave - 2] = buf[i];
        count++;
    }
    i++;
    countsave = count;
    for (; buf[i] != '\n'; i++) {
        msg[i-countsave-3] = buf[i]; 
    }

    std::cout << number << " " << type << " " << recipient << " " << msg << "\n";

    if (!strcmp(type, "mail")) {
        send(client_sockv[atoi(recipient)-1], buf, sizeof(buf), 0);
        std::cout << buf; // 2 mail 1 privet!
    }
}

void accept_connections() {
    
    WSADATA ws;
    WSAStartup(MAKEWORD(2, 2), &ws);

    s = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN sa;
    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons(1234);

    bind(s, (const sockaddr*)&sa, sizeof(sa));

    listen(s, 100);
    
    SOCKADDR_IN client_addr;

    int client_addr_size = sizeof(SOCKADDR_IN);
    int i = 0;
    while (true) {
        client_sockv.push_back(accept(s, (sockaddr*)&client_addr, &client_addr_size));
        client_addrv.push_back(client_addr);
        std::cout << "connect is OK! ip:port " << inet_ntoa(client_addrv[i].sin_addr) << ":" << ntohs(client_addrv[i].sin_port) << "\n";
        char ichar[10];
        memset(ichar, 0, sizeof(ichar));
        itoa(i+1, ichar, 10);
        send(client_sockv[i], ichar, sizeof(ichar), 0);
        i++;
    }
}

int main()
{
    setlocale(LC_ALL, "");
    std::thread connects(accept_connections);

    char buf[20000];
    memset(buf, 0, sizeof(buf));
    while (1) {
        for (int i = 0; i < client_addrv.size(); i++) {
            if (recv(client_sockv[i], buf, sizeof(buf), 0) > 0) {
                if(buf[0] != ' ')msgProc(buf);
                memset(buf, 0, sizeof(buf));
            }
        }
    }
}


как это выглядит по итогу
6631940e678c4937188806.jpeg


upd. скрин и код немного разных версий, в коде там где std::cout'ы там указано в комментариях что по итогу выводит

сообщение вводится в окне соединение 2 и выводится в окне соединение 1

upd. опытным путем выяснил что проблема в sizeof(buf) который почему то равен 8 после передачи в функцию
делал статическим - не помогло, объясните пожалуйста как так может быть?
  • Вопрос задан
  • 88 просмотров
Пригласить эксперта
Ответы на вопрос 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
выяснил что проблема в sizeof(buf) который почему то равен 8 после передачи в функцию

https://qna.habr.com/answer?answer_id=2411176#answ...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы