C ++套接字 - 我只能发送字符吗?

时间:2010-08-10 22:32:37

标签: c++ sockets winapi

我正在使用带有win32窗口的同步套接字,并使用send()和recv()函数通过Internet TCP发送数据;

我在想什么,我将如何通过tcp套接字发送一些整数甚至我自己的类/结构?因为send()函数只允许我发送字符。

我只需要发送字符然后将它们转换为带有atoi()的整数吗?或者,如果我想发送一个类结构,我会发送许多字符串,然后将它们放在变量中。一个接一个。

4 个答案:

答案 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.AsioBoost.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,它应该不是问题。