C++ Sockets - Can i only send characters?
I'm using synchronised sockets with a win32 window, and using the send() and recv() function to send data over internet TCP;
what i'm wondering, how would i send some integers or even my own class/structure over the tcp socket? because the send() function only lets me 开发者_C百科send characters.
Would i just have to send characters and then maybe convert them to integer with atoi()? or if i wanted to send a class structure, would i send many strings over and then put them in the variables.. one by one.
It isn't sending characters in the textual sense - it's sending contiguous arrays of bytes, which it refers to using a char*. You can point to the bytes of any value type this way, so if you wanted to send an int,
int A = 5;
const char* pBytesOfA = (const char*)&A;
int lengthOfBytes = sizeof(A);
send(socket, pBytesOfA, lengthOfBytes, flags);
It depends on what you want to do. One simple possibility is:
Let's assume that an int
has 32 significant bits and that negative values are encoded in two's-complement. Then you can send one int
as four chars
:
bool send_int(int fd, int i)
{
unsigned char buf[4];
buf[0] = (i >> 24) & 0xff;
buf[1] = (i >> 16) & 0xff;
buf[2] = (i >> 8) & 0xff;
buf[3] = (i >> 0) & 0xff;
return ((unsigned) send(fd, buf, sizeof buf, 0) == sizeof buf);
}
On the receiving side you have to read four bytes and then combine their values so that they form an int
again.
There are many other possibilities for encoding int
s and other data types as a stream of bytes. The above is just a simple example.
Rather not do this yourself, use libraries which do this for you, like Boost.Asio and Boost.Serialization.
Boost Asio is a library which replaces sockets and even provides an interface like C++ iostreams and will handle sending/recieving builtin types like int
for you.
Boost Serialization enables you to easily serialize your classes so you can send them over the network.
IF you cant use additional libraries, you will have to send the data manually over plain sockets - make sure you dont forget to use htons
, ntohs
, htonl
and ntohl
functions, or your code will break when the two communicating computers use different endianess (byte order).
small snippet:
// sender:
unsigned long to_send = 123;
unsigned long to_send_n = htonl(to_send); // convert to network byte order
send(send_socket, (const char*)(&to_send_n), sizeof(unsigned long), flags);
// reciever:
char recv_buf[sizeof(unsigned long)];
recv(recv_socket, recv_buf, sizeof(unsigned long)); //recieve number
unsigned long recieved = ntohl(*((unsigned long*)recv_buf), flags); // convert back to host byte order
Since these functions only exist for unsigned types, you will be limited to unsigned types..
A C(++) char
is not the same as a character. A char
is simply an integer type with at least (and usually exactly) 8 bits. A char
often does represent an ASCII character (or nowadays, a UTF-8 code unit), but it can also represent arbitrary binary data, which is the case with send()
and recv()
.
Now, there are some protocols (e.g., SMTP) which do assume that the data is text, and may mangle binary data that happens to contain bytes like 0x0A (line feed) or 0x00 (C string terminator). In this case, you do need to use a binary-to-text encoding like Base64. But it shouldn't be an issue if you're working with TCP directly.
精彩评论