我正在使用带有win32窗口的同步套接字,并使用send()和recv()函数通过Internet TCP发送数据;
我在想什么,我将如何通过tcp套接字发送一些整数甚至我自己的类/结构?因为send()函数只允许我发送字符。
我只需要发送字符然后将它们转换为带有atoi()的整数吗?或者,如果我想发送一个类结构,我会发送许多字符串,然后将它们放在变量中。一个接一个。
答案 0 :(得分:5)
它不是在文本意义上发送字符 - 它发送连续的字节数组,它使用char *引用。您可以通过这种方式指向任何值类型的字节,因此如果您想发送一个int,
int A = 5;
const char* pBytesOfA = (const char*)&A;
int lengthOfBytes = sizeof(A);
send(socket, pBytesOfA, lengthOfBytes, flags);
答案 1 :(得分:2)
这取决于你想做什么。一个简单的可能性是:
假设int
有32个有效位,负值用二进制补码编码。然后,您可以发送一个int
作为四个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);
}
在接收方,您必须读取四个字节,然后合并它们的值,以便它们再次形成int
。
将int
和其他数据类型编码为字节流还有许多其他可能性。以上只是一个简单的例子。
答案 2 :(得分:2)
而不是自己动手,请使用为您执行此操作的库,例如Boost.Asio和Boost.Serialization。
Boost Asio是一个替换套接字的库,甚至可以提供interface like C++ iostreams,并为您处理发送/接收内置类型,如int
。
Boost Serialization使您可以轻松地序列化类,以便通过网络发送它们。
如果您无法使用其他库,则必须通过普通套接字手动发送数据 - 确保您不要忘记使用htons
, ntohs
, htonl
and ntohl
functions, or your code will break when the two communicating computers use different endianess (byte order).
小片段:
// 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
由于这些函数仅适用于无符号类型,因此您将仅限于无符号类型..
答案 3 :(得分:0)
C(++)char
与字符不同。 char
只是一个整数类型,至少有(并且通常精确地)8位。 char
通常 表示ASCII字符(或者现在是UTF-8代码单元),但它也可以表示任意二进制数据,send()
就是这种情况和recv()
。
现在,有一些协议(例如,SMTP)做假设数据是文本,并且可能破坏恰好包含字节的二进制数据,如0x0A(换行)或0x00(C字符串终止符)。在这种情况下,您需要使用像Base64这样的二进制文本编码。但是如果你直接使用TCP,它应该不是问题。