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);