【发布时间】:2013-12-17 20:52:11
【问题描述】:
我正在为大学做一个项目。需要编写一个套接字和一个服务器和一个客户端通过这个套接字进行通话的代码。消息是这样的:
typedef struct {
/** message type */
char type;
/** message length in byte */
unsigned int length;
/** message buffer */
char *buffer;
} message_t;
我编写了 Socket 的代码,现在我遇到了两个函数的问题:sendMessage 和 receiveMessage
/** read a message from the socket --- properly split the message and put it in the struct message_t
* \param sc file descriptor of the socket
* \param msg
*
* \retval lung length of the buffer read, if it's OK
* \retval -1 if there are errors (set errno)
*
*
*/
int receiveMessage(int sc, message_t * msg) {
int lung;
lung = read(sc, &(msg->type), sizeof(char));
if(lung == 0)
return -1;
if(lung == -1)
return -1;
lung = read(sc, &(msg->length), sizeof(unsigned int));
if(lung == 0)
return -1;
if(lung == -1)
return -1;
if(msg->length > 0) {
msg->buffer = malloc (sizeof(char)*msg->length);
lung = read(sc, &(msg->buffer), sizeof(char)*msg->length);
if(lung == 0)
return -1;
if(lung == -1)
return -1;
}
return lung;
}
这是发送消息
/** write a message on the socket --- should send only significant byte of the buffer (msg->length byte) -- must use only 1 write
* \param sc file descriptor of the socket
* \param msg address of the struct
*
* \retval n no. of char sent (if its OK)
* \retval -1 if there are errores (set errno)
*
*
*/
int sendMessage(int sc, message_t *msg) {
int n,lung;
lung = sizeof(unsigned int) + sizeof(char) + (sizeof(char)*msg->length);
record = malloc (lung);
sprintf(record,"%c%u%s",msg->type,msg->length,msg->buffer);
n = write(sc,record,lung);
if(n == 0)
return -1;
return n;
}
测试返回接收消息的无效参数并且没有消息在套接字中写入和读取,我认为问题在于缓冲区的长度(无符号整数) 有什么建议吗?
【问题讨论】:
-
sprintf格式化人类可读的字符串,而不是将数据格式化到二进制缓冲区中。因此,我立即看到错误的一件事是您的缓冲区太小,因为msg->length可能大于sizeof(unsigned int)。 -
memcpy将复制字节,但请记住unsigned int的大小和字节序可能因平台而异。您可以使用stdint.h中的大小类型来处理大小,您可以使用htonl等函数来处理字节序。 -
@DarkFalcon AF_UNIX 套接字在机器上是本地的,不会有字节序问题。
-
@nos 对,抱歉,我没有注意到这是
AF_UNIX套接字。与其他机器通信的套接字会出现字节序问题,例如AF_INET。