m2.mbcp/src/group.cc
2006-03-06 16:40:15 +00:00

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