J'essaie d'autoriser plusieurs clients à se connecter à un hôte à l'aide de SELECT. Dis-je connecter chacun un, dites-leur de passer à un autre port, puis de vous reconnecter sur un nouveau port? Ou sélectionnerons-moi permettez-moi de connecter plusieurs clients au même port?
Ceci est le code client: p> Ceci est le code du serveur: p> 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);
3 Réponses :
De nombreux clients peuvent se connecter au même port p>
Vous devez d'abord écouter, puis sélectionnez P>
Lorsque SELECT vous indique, vous avez une nouvelle connexion, puis acceptez. Il vous indique que le client connecté en signalant une lecture sur votre socket FD. P>
Vous devez marquer la prise de serveur en tant que telle ( Veuillez noter que si vous ne travaillez pas avec sockets non bloquants em> Il y a une chance écouter (2) code>) mais seulement appeler
accepter (2) code> lors de votre retour de
Sélectionnez (2) Code> Quand il devient lisible - cela signifie une nouvelle demande de connexion est en attente. P>
SELECT (2 ) Code> retourner et appeler
accepter (2) code> - le client de connexion peut déposer la tentative pendant cette période - afin que vous puissiez toujours bloquer. P>
Les connexions TCP sont identifiées par l'adresse IP et le numéro de port de les deux extrémités em> de la connexion. Il convient donc d'avoir beaucoup de clients (qui auront généralement des numéros de port attribués au hasard) pour se connecter à un seul porteur de serveur. Vous créez une prise et Il est typique d'utiliser un Bind () code> à un port sur lequel
ÉCOUTER () CODE>, puis attendez que les clients viennent frapper dessus. Si vous ne vous dérangeez pas de bloquer, vous pouvez simplement appeler
accepter () code> sur elle directement, mais vous ne ferez aucune boucle de délai ou rien. Sinon, vous pouvez
SELECT () CODE> sur la prise d'écoute, qui sera lisible lorsqu'un client tente de se connecter, puis d'appeler
accepter () p> p> P> P> P> P> P >
accepter () code> retournera une prise nouvellement créée, qui est la prise réelle pour parler au client. La prise d'écoute d'origine continue d'écouter, et plus de connexions peuvent être acceptées dessus. P>
Sélectionnez () CODE> boucle pour rechercher la lisibilité sur la prise d'écoute et tout des prises connectées. Ensuite, lorsque
SELECT () CODE> Retourne que vous vérifiez simplement si la prise d'écoute a été lisible, et si oui,
accepte () code>; Sinon, recherchez une prise connectée lisible et manipulez-la. P>
fd_set fds;
int max = 0, reuse = 1;
struct timeval tv;
int server;
std::vector<int> connected;
// create server listening socket
server = socket(PF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto);
setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)); // optional, but recommended
if (bind(server, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
// error, could not bind server socket
}
if (listen(server, 8) < 0) {
// error, could not listen on server port
}
// loop looking for connections / data to handle
while (running) {
FD_ZERO(&fds);
FD_SET(server, &fds);
if (server >= max) max = server + 1;
for (std::vector<int>::iterator it = connected.begin(); it != connected.end(); ++it) {
FD_SET(*it, &fds);
if (*it >= max) max = *it + 1;
}
tv.tv_sec = 2; tv.tv_usec = 0;
if (select(max, &fds, NULL, NULL, &tv) > 0) {
// something is readable
if (FD_ISSET(server, &fds)) {
// it's the listener
connected.push_back(accept(server, (struct sockaddr *)&addr));
}
for (std::vector<int>::iterator it = connected.begin(); it != connected.end(); ++it) {
if (FD_ISSET(*it, &fds)) {
// handle data on this connection
}
}
}
}