【问题标题】:recvfrom: Bad address, sendto: Address family not supported by protocolrecvfrom:错误地址,sendto:协议不支持的地址族
【发布时间】:2012-12-03 14:34:24
【问题描述】:

我正在尝试在 C 中实现一个小的 UDP-服务器/客户端应用程序,并在服务器端遇到两个错误:recvfrom: Bad address && sendto: Address family not supported by协议。我搜索了错误并搜索了答案,但不幸的是,它们并没有真正有帮助......也许我以错误的方式投射参数并且没有得到它。我希望你能给我一个提示:)。

#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <errno.h>

#define BUFFSIZE 256
#define IP "127.0.0.1"
#define PORT 7755

int main(void){

  int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
  char buffer[1] = "s";

  struct sockaddr_in src_addr;
  struct sockaddr_in dest_addr;

  src_addr.sin_family = AF_INET;
  src_addr.sin_port = htons(PORT);
  src_addr.sin_addr.s_addr = inet_addr(IP);

  if(socket_fd==-1)
    perror("socket");

  if(bind(socket_fd, (struct sockaddr*)&src_addr, sizeof(src_addr))==-1)
    perror("bind");

  if(recvfrom(socket_fd, buffer, 2, 0, (struct sockaddr*)&dest_addr, (unsigned int *)sizeof(struct sockaddr_in))==-1)
    perror("recvfrom");

  if(sendto(socket_fd, buffer, 2, 0,(struct sockaddr*)&dest_addr, sizeof(dest_addr))==-1)
    perror("sendto");

  if(close(socket_fd)==-1)
    perror("close");

  return 0;

}

【问题讨论】:

标签: c udp chat recv sendto


【解决方案1】:

引用 Fedora 18 Beta recv/recvmsg/recv 来自主页:

ssize_t recv(int sockfd, void *buf, size_t len, int flgags);  
ssize_t recvfrom(int sockfd, void*buf, size_t len, int flags,  
       struct sockaddr *src_addr, socklen_t* addrlen); 

recvfrom 应调整自:

   recvfrom(socket_fd, buffer, 2, 0, (struct sockaddr*)&dest_addr, 
             (unsigned int *)sizeof(struct sockaddr_in) == -1)

收件人:

   recvfrom (socket_fd, buffer, sizeof(buffer), 0, 
            (struct sockaddr*)&dest_addr, &addrlen);
  • 你没有初始化dest_addr
  • 数组(eg _buffer_)始终是指针类型
  • 在生产程序中缓冲区必须大得多(动态大小),否则缓冲区的固定大小将成为堆栈粉碎的目标(安全漏洞)。

【讨论】:

    【解决方案2】:

    您需要将有效指针传递给recvfrom。 (unsigned int *)sizeof(struct sockaddr_in) 不是有效的指针。

    改变

     if(recvfrom(socket_fd, buffer, 2, 0, (struct sockaddr*)&dest_addr, 
                 (unsigned int *)sizeof(struct sockaddr_in) == -1)
    

    例如

     socklen_t len = sizeof dest_addr;
     if(recvfrom(socket_fd, buffer, 2, 0, 
                 (struct sockaddr*)&dest_addr, &len) == -1)
    

    你也在构造一个你发送的无效数组,你的数组长度为 1,但你告诉 sendto/recvfrom 它的长度为 2。所以改变

    char buffer[1] = "s";
    

    到

    char buffer[] = "s";
    

    (字符串“s”是字符's'和一个0字节,所以buffer在后一种情况下的长度为2。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-20
      • 1970-01-01
      • 2018-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 2018-11-01
      相关资源
      最近更新 更多