The send function in winsock2 accepts only char pointers. How do I send integers or objects through it too?
3 Answers
const char *buf
which you need to pass to send()
function as an argument is just a pointer to array of bytes. You need to convert integers to bytes:
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);
and reading code:
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);
and complex objects needs to be serialized to stream of bytes.
Note 1: The code sample is valid iff both server and client use the same platforms (x32 / x64 / ...) that means int
has the same amount of bytes and byte order is the same.
Note 2: Writing code should check that there is no buffer (MAX_BUF_SIZE
) overflow on each step.
-
for an integer should I use reinterpret_cast
(i)? – Pilpel Aug 22 '11 at 09:40 -
1"(that is easy)" - for those who know how to. If you have to ask this question, you're not going to find `htons` and `htonl()`. (@Pilpel: "hton" stands for "Host TO Network"; it changes the order of bytes to match that of TCP/IP. On receive, you'd use a "ntoh" function. Both exist in 's' (short, 16 bits) and 'l' (long, 32 bits) version. – MSalters Aug 22 '11 at 09:45
-
How does this answer my question? the ntoh functions don't take char pointers and make them integers – Pilpel Aug 22 '11 at 11:38
-
@Pilpel: Not directly. It's the step you need to do before `reinterpret_cast
(&result_of_htonl)` – MSalters Aug 22 '11 at 11:45 -
I see. So the "host" word in hton could be both client and server code, right? – Pilpel Aug 22 '11 at 11:50
-
@Pilpel: I don't understand, why we need to swap the bytes before putting them to the buffer and then do a reverse operation. I would use `memcpy` to copy bytes (with assumption that `int` = 4 bytes on server and client platform and both platforms are e.g. x86). – dma_k Aug 22 '11 at 13:36
-
I'm confused. Could you post some lines of code to clear things up? – Pilpel Aug 22 '11 at 13:41
-
@Pilpel: I've added the sample. Sorry, it is not tested, but I hope you can catch the idea. – dma_k Aug 22 '11 at 14:33
Just store the value into a variable and then type-cast the variable to char*
. The send()
and recv()
functions operate on binary data, despite taking char*
parameters.
Sending:
int int_data = 4;
send(sock, (char*) &int_data, sizeof(int), 0);
Reading:
int int_data;
recv(sock, (char*) &int_data, sizeof(int), 0);

- 555,201
- 31
- 458
- 770
Generally, the easiest way is to print the integer or object to a string, and send that string. Textual representations are more portable, and also easier to debug.
std::stringstream
may be a useful class both to create the string and parse it on the other end.

- 173,980
- 10
- 155
- 350
-
This serialization is ineffective. As long as you don't need a crossplatform portability you can use a memcpy semantik. Take the address of the object and its size and pass address and size to the winsock functions. You will need a cast here. When your data contain pointers to other objects you can't use the memcpy style. In that case you need serialization. – harper Aug 22 '11 at 11:10
-
Ineffective? You even admit it's cross-platform, so it must certainly work. – MSalters Aug 22 '11 at 11:47
-
So assuming I have an object with two data members, x and y, when x = 10 and y = 20. Do you recommend me to send it as plain text like this: "10|20"? – Pilpel Aug 23 '11 at 16:13