【问题标题】:Multi Client Server, Multi interface, Multi IP version Socket多客户端服务器,多接口,多IP版本Socket
【发布时间】:2013-07-23 20:05:09
【问题描述】:

我想创建一个在所有接口上都接受 IPv4 和 IPv6 的服务器。

它似乎不适用于任何地址,包括 localhost、127.0.0.1、::1、192.168.1.26。 我错过了什么?

根据getaddrinfo(3),因为 ai_family 设置为 AI_PASSIVE 标志。 '返回的套接字地址将包含“通配符地址”'

这是我目前的代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/times.h>
#include <errno.h>


#define MAXBUF  1024

const char* PORTNUM = "687";

int init_address(struct addrinfo* hints)
{
    hints->ai_flags=     AI_PASSIVE;
    hints->ai_family=    AF_UNSPEC;
    hints->ai_socktype=  SOCK_DGRAM;
    hints->ai_protocol=  IPPROTO_UDP;
    return 1;
}

socklen_t init_socket(struct addrinfo* res, int* sockfd)
{
    struct addrinfo* ressave;
    struct sockaddr_in* all_interface;
    socklen_t addrlength;

    ressave=res;
    all_interface = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));

    do {/* each of the returned IP address is tried*/
        (*sockfd) = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if ((*sockfd)<0)
            continue; /* fail, try next one*/

        if (bind((*sockfd), (struct sockaddr*)all_interface, sizeof(all_interface)) == 0)
            break; /*success*/

        close(*sockfd);

    }while(res->ai_next != NULL  && (res = res->ai_next)!= NULL);

    if(&addrlength)
        addrlength = res->ai_addrlen;

    freeaddrinfo(ressave);
    free(all_interface);

    return addrlength;
}

int doprocessing(char* buffer, size_t buff_size)
{
    return 0;
}

int peak_data(char* buffer, size_t buff_size)
{
    return 0;
}

int main(int argc, char const *argv[])
{
    int sockfd, newsockfd;
    int bytes_read;
    char* port;
    char buffer[MAXBUF];
    pid_t pid;
    socklen_t addrlen, len;
    struct addrinfo* socket_info;
    struct addrinfo* res;
    struct addrinfo* backup_res;
    struct sockaddr* cliaddr;
    int  n;

    socket_info = (struct addrinfo*)malloc(sizeof(struct addrinfo));
    res = (struct addrinfo*)malloc(sizeof(struct addrinfo));

    memset(socket_info, 0, sizeof(struct addrinfo));
    init_address(socket_info);


    if((n = getaddrinfo(NULL, PORTNUM, socket_info, &res)) !=0)
    {
        printf("multi_server: error for %s: %s", PORTNUM, gai_strerror(n));
        exit(0);
    }

    if ((addrlen = init_socket(res, &sockfd)) < 0)
    {
        printf("multi_server: Socket or Bind error");
        exit(0);
    }

    free(socket_info);

    cliaddr=malloc(addrlen);

    len=addrlen;

    printf("\nUDP Server: waiting for connection...");
    while (1) {
        bytes_read = recvfrom(sockfd, buffer, MAXBUF-1, MSG_PEEK, cliaddr, &len);

        if (bytes_read > 0) {
            // a connection has been established
            buffer[MAXBUF] = '\0';
            printf("\nUDP Server: received %d bytes ", bytes_read);
            pid = fork();

            if (pid < 0) {
                perror("UDP Server: ERROR while forking new process.\n");
                exit(1);
            }
            // check if the process ID is zero
            if (pid == 0) {
                // we are now inside the new forked process
                if(peak_data(buffer, bytes_read))
                {
                    doprocessing(buffer, bytes_read);
                }
                printf("Now in %d\n", pid);
                close(sockfd);
                exit(0);
            }
        }
    }
}

【问题讨论】:

    标签: c sockets network-programming


    【解决方案1】:

    你没有错过任何东西。它正在接受与您所说的 ::1 的连接?然后它将接受 ipv6 连接。由于 IPv6 是向后兼容的,如果您创建了正确的 ipv6 套接字,它也应该能够发送和接收 ipv4 数据包。

    【讨论】:

    • 请注意,至少在 Windows 下,您需要执行 setsockopt(my_sock, IPPROTO_IPV6, IPV6_V6ONLY, &val); (其中 val 是一个值为 0 的整数变量)以禁用 IPV6_V6ONLY 模式,从而允许 IPv6 套接字也与 IPv4 连接一起使用。
    • @JeremyFriesner 忘记关闭我的防火墙并以 root 身份运行,因为它的端口号较低
    猜你喜欢
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多