多客户端服务器,多接口,多IP版本套接字

时间:2013-07-23 20:05:10

标签: c sockets network-programming

我想在所有接口上创建一个同时接受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);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

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