【问题标题】:UDP C Server sendto() error: Can't assign requested addressUDP C 服务器 sendto() 错误:无法分配请求的地址
【发布时间】:2015-01-14 13:52:18
【问题描述】:

我正在使用 UDP 用 C 语言编写一个基本的客户端/服务器程序。该程序的想法是客户端向服务器发送一条消息,服务器接收它,然后将其回显给客户端(目标是测量 UDP 的 RTT)。不幸的是,在服务器端,当程序尝试调用 sendto() 来回显消息时,我收到错误“无法分配请求的地址”。

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>

#define SERVER_PORT 7000 
#define MAX_PENDING 10 
#define MAX_LINE 1024000

int main() 
{ 
    struct sockaddr_in sin, sout;
    socklen_t soutLen; 
    char buf[MAX_LINE]; 
    int len;
    int msgLen;
    int s; 
    char *msg;
    if( (s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
        perror("could not establish UDP socket");
        exit(1);
    }

    /* build address data structure */ 
    bzero((char *)& sin, sizeof( sin)); 
    sin.sin_family = AF_INET; 
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = htons(SERVER_PORT);

    if( (bind(s, (struct sockaddr *)&sin, sizeof(sin))) < 0){
        perror("udpServer: bind"); 
        exit( 1); 
    }

    while(1){
        if((msgLen = recvfrom(s, buf, sizeof(buf), 0,(struct sockaddr *)&sout, &soutLen))<0){
            perror("udpServer: recvfrom()"); 
            exit( 1); 
        }

        if( (sendto(s, buf, msgLen, 0, (struct sockaddr *)&sout, sizeof(sout)))<0 ){
            perror("udpServer: sendto()"); 
            exit( 1); 
        }
        free(msg);
    }

} 

提前致谢:我是 C 的新手,非常感谢任何建议!

【问题讨论】:

    标签: c networking udp runtime-error server


    【解决方案1】:

    问题是你传递给sendtosout 不正确,因为你在传递给recvfrom 时没有正确设置它的大小:

    man recvfrom:

     ssize_t
     recvfrom(int socket, void *restrict buffer, size_t length,
              int flags, struct sockaddr *restrict address,
              socklen_t *restrict address_len);
    

    如果address不是空指针且socket不是面向连接的,则填写消息的源地址。address_len参数为一种 value-result 参数,初始化为与地址关联的缓冲区的大小,并在返回时修改以指示地址的实际大小 存放在那里。

    当您将&amp;sout 传递给recvfrom 时,您还必须告诉recvfrom 您要传入的结构的大小,以便它知道可以在那里写入多少数据——soutLen 既是输入参数和输出参数。由于您没有初始化soutLen,它的值可能小于结构的实际大小,这意味着您最终在sout 中得到的值无效。

    所以你需要初始化soutLen:

    struct sockaddr_in sin, sout;
    socklen_t soutLen = sizeof(sout); 
    

    然后,您应该将此值作为大小传递给 sendto 而不是 sizeouf(sout)(这可能不是必需的,但这是一种很好的做法):

       if( (sendto(s, buf, msgLen, 0, (struct sockaddr *)&sout, soutLen))<0 ){
    

    还请注意,您正在释放您从未分配过的msg。这无关紧要,但以后可能会导致问题。

    希望这会有所帮助。

    【讨论】:

    • 这确实是问题所在。谢谢!
    猜你喜欢
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2017-03-29
    • 2011-03-12
    • 2011-10-13
    相关资源
    最近更新 更多