对socket编程的理解(3)

int getaddrinfo(const char *node,          //host name to connect to or an IP address
                const char *service,    //port number, /etc/services
                const struct addrinfo *hints,    //fill with relevant information, only ai_flags, ai_family, ai_socktype, ai_protocol
                struct addrinfo **res   
                );

上面的服务端程序是通过fork()函数来实现容许多个客户端进行连接的,下面我要用select()函数来实现多个客户端的连接。当然,也同时用了getaddrinfo()这种新特性。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define PORT "1234"

void *get_in_addr(struct sockaddr *sa) {
    if(sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(void) {
    fd_set    master;
    fd_set    read_fds;
    int    fdmax;

int    listener;
    int    newfd;
    struct sockaddr_storage remoteaddr;
    socklen_t    addrlen;

char    buf[256];
    int    len;

char    remoteIP[INET6_ADDRSTRLEN];

int    yes = 1;
    int    i, j, rv;
//    int    client[100], n;

struct addrinfo hints, *ai, *p;

FD_ZERO(&master);
    FD_ZERO(&read_fds);

memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    if((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
        perror("getaddrinfo");
        return 1;
    }

for(p = ai; p != NULL; p = p->ai_next) {
        listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if(listener < 0) {
            continue;
        }

setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

if(bind(listener, p->ai_addr, p->ai_addrlen) < 0) {
            close(listener);
            continue;
        }

break;
    }

if(p == NULL) {
        perror("socket and bind");
        return 2;
    }

freeaddrinfo(ai);

if(listen(listener, 10) == -1) {
        perror("listen");
        return 3;
    }

FD_SET(listener, &master);

fdmax = listener;

while(1) {
        printf("HERE!!! BEFORE SELECT\n");
        read_fds = master;
        if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
            perror("select");
            return 4;
        }

printf("HERE!!! AFTER SELECT\n");

for(i = 0; i <= fdmax; i++) {
            printf("round i is %d\n", i );
            if(FD_ISSET(i, &read_fds)) {
                printf("isset i is %d\n", i );
                if(i == listener) {
                    addrlen = sizeof(remoteaddr);
                    newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen);
                    printf("listener is %d, newfd is %d,listener i is %d\n", listener, newfd, i);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/144cc584406619692f9e27ee5a0a01a3.html