Функция отправки в winsock2 принимает только указатели на символы. Как мне отправить через него целые числа или объекты?
Отправить другие типы данных в winsock2
Ответы (3)
const char *buf
, который вам нужно передать send()
функции в качестве аргумента, это просто указатель на массив байтов. Вам нужно преобразовать целые числа в байты:
const int MAX_BUF_SIZE = 1024;
int int_data = 4;
const char *str_data = "test";
char *buf = (char*) malloc(MAX_BUF_SIZE);
char *p = buf;
memcpy(&int_data, p, sizeof(int_data));
p += sizeof(int_data);
strcpy(p, str_data);
p += strlen(str_data) + 1;
send(sock, buf, p - buf, 0);
free(buf);
и чтение кода:
const int MAX_BUF_SIZE = 1024;
int int_data = 0;
const char *str_data = NULL;
char *buf = (char*) malloc(MAX_BUF_SIZE);
char *p = buf;
recv(sock, buf, MAX_BUF_SIZE, 0);
memcpy(p, &int_data, sizeof(int_data));
p += sizeof(int_data);
str_data = malloc(strlen(p) + 1);
strcpy(str_data, p);
p += strlen(p) + 1;
free(buf);
а сложные объекты необходимо сериализовать в поток байтов.
Примечание 1. Пример кода действителен, если и сервер, и клиент используют одни и те же платформы (x32 / x64 / ...), что означает, что int
имеет одинаковое количество байтов и порядок байтов одинаков.
Примечание 2: Написание кода должно проверять отсутствие переполнения буфера (MAX_BUF_SIZE
) на каждом шаге.
htons
и htonl()
. (@Pilpel: hton означает Host TO Network; он изменяет порядок байтов в соответствии с порядком байтов TCP / IP. При приеме вы должны использовать функцию ntoh. Оба существуют в 's' (короткое, 16 бит) и ' l '(длинная, 32 бита) версия.
- person MSalters; 22.08.2011
reinterpret_cast<char*>(&result_of_htonl)
- person MSalters; 22.08.2011
memcpy
для копирования байтов (при условии, что int
= 4 байта на серверной и клиентской платформе, и обе платформы, например, x86).
- person dma_k; 22.08.2011
Просто сохраните значение в переменной, а затем приведите переменную к char*
. Функции send()
и recv()
работают с двоичными данными, несмотря на принятие char*
параметров.
Отправка:
int int_data = 4;
send(sock, (char*) &int_data, sizeof(int), 0);
Чтение:
int int_data;
recv(sock, (char*) &int_data, sizeof(int), 0);
Как правило, самый простой способ - вывести целое число или объект в строку и отправить эту строку. Текстовые представления более переносимы, а также их легче отлаживать.
std::stringstream
может быть полезным классом как для создания строки, так и для ее анализа на другом конце.