【问题标题】:Write and Read - Socket AF_UNIX写入和读取 - 套接字 AF_UNIX
【发布时间】: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

标签: c sockets


【解决方案1】:

检查手册页以了解有关 EINVAL 的内容,您要么发送无效套接字,要么发送无效指针到 read()。尝试调试您的哪个 read() 调用也失败了。

然而这是错误的:

lung = read(sc, &(msg->buffer), sizeof(char)*msg->length);

你的缓冲区是一个指针,你想从它指向的任何地方读取数据,而不是它的地址。所以应该是

lung = read(sc, msg->buffer, sizeof(char)*msg->length);

【讨论】:

    猜你喜欢
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 2012-06-09
    • 2020-09-15
    • 2022-01-25
    相关资源
    最近更新 更多