140 lines
3 KiB
C++
140 lines
3 KiB
C++
|
|
#include "group.h"
|
|
|
|
#include <iostream>
|
|
|
|
#define DEBUG 0
|
|
|
|
Group::Group(std::list<HostId> group, short index){
|
|
_hosts = group;
|
|
_socket_desc = socket(AF_INET, SOCK_DGRAM, 0);
|
|
_index = index;
|
|
|
|
/* et l'autre variante : AF_UNIX */
|
|
if (_socket_desc < 0){
|
|
/* error */
|
|
perror("Creation de la socket impossible");
|
|
fprintf(stderr,"BOUM at %s:%d",__FILE__,__LINE__);
|
|
|
|
throw new eGroupNotConstructed();
|
|
}
|
|
|
|
struct sockaddr_in * myaddr = new sockaddr_in;
|
|
|
|
bzero(myaddr,sizeof(sockaddr_in));
|
|
myaddr->sin_family = AF_INET;
|
|
myaddr->sin_port = htons(0);
|
|
myaddr->sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
if (bind(_socket_desc,(struct sockaddr *)myaddr,sizeof(sockaddr_in)) < 0) {
|
|
//FIXME : throw something
|
|
perror("Attachement de la socket impossible");
|
|
fprintf(stderr,"BOUM at %s:%d",__FILE__,__LINE__);
|
|
|
|
throw new eGroupNotConstructed();
|
|
}
|
|
|
|
//FIXME: définir une liste avec les structures...
|
|
std::list<HostId>::iterator hiIter;
|
|
for (hiIter = _hosts.begin();
|
|
hiIter != _hosts.end();
|
|
hiIter++){
|
|
// pour chacun des hostId, on ouvre une socket
|
|
HostId &hid = *hiIter;
|
|
std::cout << "HOST: " <<hid.host <<std::endl;
|
|
//printf("HOST: %s\n",hid.host.c_str());
|
|
|
|
/* structure hostent qui sera remplie par gethostbyname */
|
|
struct hostent * hp;
|
|
struct sockaddr_in * addr = new sockaddr_in;
|
|
int addr_len = sizeof(struct sockaddr_in);
|
|
|
|
/* Recuperer l'adresse IP du serveur */
|
|
if((hp = gethostbyname(hid.host.c_str())) == NULL) {
|
|
fprintf(stderr,
|
|
"Erreur client : echec gethostbyname sur %s\n",
|
|
hid.host.c_str()) ;
|
|
|
|
throw new eGroupNotConstructed();
|
|
}
|
|
|
|
addr->sin_family = AF_INET;
|
|
addr->sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
|
|
addr->sin_port = htons(hid.port);
|
|
|
|
_addrs.push_back(addr);
|
|
}
|
|
}
|
|
|
|
|
|
void Group::broadcast(Message & msg){
|
|
if (DEBUG)
|
|
printf("Group::broadcast -- enter\n");
|
|
std::vector<sockaddr_in *>::iterator saIter;
|
|
|
|
std::list<int> raList;
|
|
// choisir aléatoirement l'ordre des sites recepteurs
|
|
for (int index = 0; index < _addrs.size(); index++){
|
|
raList.push_back(index);
|
|
}
|
|
|
|
while(raList.size() > 0){
|
|
int r=rand() % raList.size();
|
|
|
|
std::list<int>::iterator it;
|
|
it = raList.begin();
|
|
for (int i=0; i<r; i++){
|
|
it++;
|
|
}
|
|
|
|
// printf("Sending to %d\n", *it);
|
|
this->sendto(msg, *it);
|
|
|
|
raList.remove(*it);
|
|
}
|
|
|
|
if (DEBUG)
|
|
printf("Group::broadcast -- exit\n");
|
|
}
|
|
|
|
short Group::getIndex(){
|
|
return _index;
|
|
}
|
|
|
|
void Group::sendto(Message &msg, short index){
|
|
sockaddr_in * addr = _addrs[index];
|
|
|
|
if (DEBUG)
|
|
printf("Group::sendto -- for\n");
|
|
|
|
int message_len = msg.getRawSize();
|
|
char * message = msg.getRaw();
|
|
|
|
int en;
|
|
|
|
if (DEBUG)
|
|
printf("Group::sendto -- got mesg\n");
|
|
|
|
sleep(1); //FIXME: de-activate
|
|
if ((en = ::sendto(_socket_desc,
|
|
message,
|
|
message_len,
|
|
0,
|
|
(struct sockaddr*)addr,
|
|
sizeof(struct sockaddr_in)) < 0)){
|
|
|
|
perror("sendto failed\n");
|
|
/* error */
|
|
throw new eGroupUnableToSend();
|
|
} else {
|
|
if (DEBUG)
|
|
printf("Group::sendto -- done\n");
|
|
}
|
|
}
|
|
|
|
short Group::getCount(){
|
|
return _addrs.size();
|
|
}
|
|
|
|
#undef DEBUG
|