I’m trying to allow multiple clients to connect to a host using select. Will I have to connect each one, tell them to move to a different port, and then reconnect on a new port? Or will select allow me to connect multiple clients to the same port?
This is the client code:
int rv;
int sockfd, numbytes;
if ((rv = getaddrinfo(hostName, hostPort, &hints, &servinfo)) != 0) {
cout << "Could not get server address.\n";
exit(1);
}
// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("Client: no socket");
continue;
}
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("Client: connect");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "Unable to connect to server.\n");
exit(2);
}
FD_SET(sockfd, &masterSet);
This is the server code:
int rv = getaddrinfo(NULL, port, &hints, &res);
int yes = 1;//Not sure what this is for, found it in Beej's
if(rv != 0){
cout<< "Error, nothing matches criteria for file descriptor.\n";
exit(1);
}
int fdInit;
for(temp = res; temp != NULL; temp = temp->ai_next){
if((fdInit = socket(temp->ai_family, temp->ai_socktype, temp->ai_protocol)) == -1){
cout << "This is not the fd you're looking for. Move along.\n";
continue; //This is not the fd you're looking for, move along.
}
if(setsockopt(fdInit, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
cout << "Doom has fallen upon this set socket.\n";
perror("setsockopt");
exit(1); //Unable to set socket, exit program with code 1
}
if(bind(fdInit, temp->ai_addr, temp->ai_addrlen) == -1){
cout << "Could not bind fd\n";
close(fdInit);
continue; //Could not bind fd, continue looking for valid fd
}
break; //If a valid fd has been found, stop checking the list
}
if(temp==NULL){
cout<<"Server failed to bind a socket\n";
exit(2);
}
cout << fdInit << endl;
//Setup the file descriptor for initial connections on specified port
freeaddrinfo(res);
FD_SET(fdInit, &masterSet);
Any help would be excellent! Thanks.
TCP connections are identified by the IP address and port number of both ends of the connection. So it’s fine to have lots of clients (which will generally have randomly assigned port numbers) to connect to a single server port.
You create a socket and
bind()it to a port on which tolisten(), and then wait for clients to come knocking on it. If you don’t mind blocking you can just callaccept()on it directly, but you won’t get to do any timeout looping or anything. Otherwise you canselect()on the listening socket, which will become readable when a client is attempting to connect, and then callaccept().accept()will return a newly created socket, which is the actual socket to talk to the client on. The original listening socket continues to listen, and more connections can be accepted on it.It’s typical to use a
select()loop to look for readability on the listening socket and any of the connected sockets. Then whenselect()returns you simply check whether the listening socket was readable, and if so,accept(); otherwise look for a readable connected socket and handle it.