C中的UDP服务器/客户端-发送至错误:协议不支持地址族 [英] UDP server/client in C - sendto error: Address family not supported by protocol

查看:207
本文介绍了C中的UDP服务器/客户端-发送至错误:协议不支持地址族的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个简单的说明性UDP服务器客户端.服务器应该根据客户端的输入来计算客户端的网络字节顺序,并将其发送回客户端.我一直在尝试整天修复此错误.任何帮助将不胜感激.这是服务器的启动和输出:

I am writing a simple illustrative UDP server client. Server should, based on the client input calculate client's network byte order, and send it back to client. I've been trying to fix this error for whole day now. Any help would be apprecciated. Here is the server start and output:

./udpserver.out 4545
from.sin_family: 12079
Little Endian

ERROR UDP_SRV_004 - can not send message to client: Address family not supported by protocol

客户端启动:

./udpclient.out localhost 4545

服务器代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <netinet/in.h>
#define BUFFER_SIZE 80

static void error(char *msg){
    perror(msg);
    exit(1);
}


int main(int argc, char ** argv){

    int socketfd, portno, fromlen, n, length;
    struct sockaddr_in server, from;
    char buffer[BUFFER_SIZE];
    char response[BUFFER_SIZE];
    const char *le = "Little Endian\n";
    const char *be = "Big Endian\n";
    const char *unk = "Unknown \n";
    int cli_family;

    if(argc!=2){
        fprintf(stderr,"Error starting the client, please start server as: %s port\n", argv[0]);
        exit(0);
    }

    if((socketfd=socket(AF_INET,SOCK_DGRAM,0))<0)
        error("ERROR UDP_SRV_001 - can not create socket");

    portno=atoi(argv[1]);

    bzero(&server,sizeof(server));
    server.sin_family=AF_INET;
    server.sin_addr.s_addr=INADDR_ANY;
    server.sin_port=htons(portno);

    if(bind(socketfd,(struct sockaddr *)&server,sizeof(server))<0)
        error("ERROR UDP_SRV_002 - can not bind server address to a socket file descriptor");

    bzero(buffer, BUFFER_SIZE);
    bzero(response,BUFFER_SIZE);
    n=recvfrom(socketfd,buffer,BUFFER_SIZE-1,0,(struct sockaddr *)&from,&fromlen);
    if (n<0)
        error("ERROR UDP_SRV_003 - can not receive client's message");

    cli_family=from.sin_family;
    printf("from.sin_family: %d\n", cli_family); 

    if (buffer[0] == 1 && buffer[1] == 2)
        strcpy(response, be);
    else if (buffer[0] == 2 && buffer[1] == 1)
        strcpy(response, le);
    else
        strcpy(response, unk);

    length=strlen(response);
    printf("%s\n",response);

    n=sendto(socketfd,response,length,0,(struct sockaddr *)&from,fromlen);
    if(n<0)
        error("ERROR UDP_SRV_004 - can not send message to client");


    return 0;
}

客户代码:

#include <stdio.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 80

static void error(char *msg){
    perror(msg);
    exit(1);
}

typedef union UNIT{
        short s;
        char c[sizeof(short)];
    }unit;

int main(int argc, char ** argv){

    int socketfd, portno, n, length;
    struct sockaddr_in  server, from;
    struct hostent *host;
    char buffer[BUFFER_SIZE];
    unit un;
    un.s=0x0102;

    if(argc!=3){
        fprintf(stderr,"Error starting the client, please start client as: %s hostname port\n", argv[0]);
        exit(0);
    }

    if((host=gethostbyname(argv[1]))==NULL)
        error("ERROR UDP_CLI_001 - no such host defined, please check your /etc/hosts file");

    portno=atoi(argv[2]);

    if((socketfd=socket(AF_INET,SOCK_DGRAM,0))<0)
        error("ERROR UDP_CLI_002 - can not create socket");

    bzero((char *)&server,sizeof(server));

    server.sin_family=AF_INET;
    server.sin_port=htons(portno);
    bcopy((char *)host->h_addr,(char *)&server.sin_addr,host->h_length);
    length=sizeof(server);

    if(sizeof(short)!=2){
      exit(0);
    }

    n=sendto(socketfd,un.c,strlen(un.c),0,(struct sockaddr *)&server,length);
    if(n<0)
        error("ERROR UDP_CLI_003 - can not send to server");
    bzero(buffer,BUFFER_SIZE);
    n=recvfrom(socketfd,buffer,BUFFER_SIZE,0,(struct sockaddr *)&from, &length);
    if(n<0)
        error("ERROR UDP_CLI_004 - can receive from server");
    printf("%s",buffer);


return 0;
}

推荐答案

在服务器中,您未能在调用sendto之前初始化fromlen.结果,未填充from.

In the server, you failed to initialize fromlen prior to the call to sendto. As a result, from was not populated.

手册页中:

如果src_addr不为NULL,并且基础协议提供了 源地址,此源地址已填写.当src_addr为 NULL,不填任何内容;在这种情况下,不使用addrlen,并且 也应该为NULL. 参数addrlen是一个值结果参数, 调用者应在调用之前初始化该大小 与src_addr关联的缓冲区,并在返回时进行修改以指示 源地址的实际大小.返回的地址是 如果提供的缓冲区太小,则将其截断;在这种情况下,addrlen 将返回一个大于提供给调用的值.

If src_addr is not NULL, and the underlying protocol provides the source address, this source address is filled in. When src_addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL. The argument addrlen is a value-result argument, which the caller should initialize before the call to the size of the buffer associated with src_addr, and modified on return to indicate the actual size of the source address. The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to the call.

recvfrom函数尝试读取fromlen的值,但由于未初始化,因此您调用未定义的行为.

The recvfrom function attempts to read the value of fromlen, but because it is not initialized you invoke undefined behavior.

初始化fromlen,这将解决该问题.

Initialize fromlen and that will address the issue.

fromlen = sizeof from;
n=recvfrom(socketfd,buffer,BUFFER_SIZE-1,0,(struct sockaddr *)&from,&fromlen);

这篇关于C中的UDP服务器/客户端-发送至错误:协议不支持地址族的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆