我正在用 C 编写一些套接字函数,但遇到了这个问题。我有一个包含三个字段的结构:
typedef struct {
char type;
unsigned int length;
char *buffer;
} message_t;
我需要包装在相同的字符串(类型、长度、缓冲区)中并将其原子地写入套接字中。之后使用 read 函数,我需要读取消息并将三个字段插入同一个结构中。我不明白如何将 int 转换为固定长度的字符串。
我正在用 C 编写一些套接字函数,但遇到了这个问题。我有一个包含三个字段的结构:
typedef struct {
char type;
unsigned int length;
char *buffer;
} message_t;
我需要包装在相同的字符串(类型、长度、缓冲区)中并将其原子地写入套接字中。之后使用 read 函数,我需要读取消息并将三个字段插入同一个结构中。我不明白如何将 int 转换为固定长度的字符串。
这就是想法,虽然我没有测试过,但我使用了一个非常相似的。
首先,您需要在两侧打包结构:
#pragma pack(1)
typedef struct {
char type;
unsigned int length;
char *buffer;
} message_t;
要发送数据包,请使用如下函数:
void SendData(char type, unsigned int length, char *data) {
message_t packet;
packet.type = type;
// convert the int to network byte order
packet.length = htonl(length);
// Here we have two options to send the packet:
// 1 with malloc and one send
packet.buffer = malloc(length);
memcpy(packet.buffer, data, length);
length +=sizeof(char);
length +=sizeof(int);
// send it in one shut
send(mySocket, (const char *)&packet, length, 0);
// release the memory
free(packet.buffer);
// 2 without malloc and two sends:
send(mySocket, (const char *)&packet, sizeof(char)+sizeof(int), 0);
send(mySocket, data, length, 0);
}
要读取另一侧的数据,请使用这样的数据:
BOOL RecvData(message_t *packet) {
// NOTE:
// if packet.buffer is not NULL, the caller of this function must
// release the memory allocate here
packet->buffer = NULL;
// at the receiver, you need 2 reads:
// 1 to know how many bytes to read
// 2 to read those bytes.
if (recv(mySocket, (char *)packet, sizeof(char)+sizeof(int), 0) > 0)
{
// convert the int to host byte order
packet->length = ntohl(packet->length);
packet->buffer=malloc(packet->length);
// if we got the memory, go ahead
if (packet->buffer != null)
{
if (recv(mySocket, packet->buffer, packet->length, 0) == packet->length)
return TRUE;
}
}
return FALSE;
}
使用 memcpy 将您的结构复制到一个空内存块中,该内存块可以解释为字符串或您喜欢的任何内容,将其发送到远程进程,将其类型转换为您的本地结构,您的值应该按照您的意愿恢复。例如
message_t my_msg;
char out_buf[MAX_LEN] = {0,};
memcpy(out_buf, my_msg, sizeof(message_t));
send_it_over_socket(out_buf);