diff --git a/include/sockets/socket.h b/include/sockets/socket.h index 36840841d34a3c1db216ff96d32a144044f01efb..a12e9e721bd69e30fc72ac80246c5faeb8a424f6 100644 --- a/include/sockets/socket.h +++ b/include/sockets/socket.h @@ -104,6 +104,11 @@ class CSocket : public CComm * */ int socket_fd; + /** + * \brief + * + */ + bool ip_v6; /** * \brief Constructor with parameters * @@ -122,7 +127,7 @@ class CSocket : public CComm * to this function is not valid or it is not properly initialized, * unexpected errors will ocurr. */ - CSocket(const std::string &comm_id,const int fd); + CSocket(const std::string &comm_id,const int fd,bool ip_v6=false); /** * \brief function to create a new socket object from a file descriptor * @@ -153,7 +158,7 @@ class CSocket : public CComm * \return a new CSocket object initialized with the parameters passed as * arguments to the function. */ - static CSocket *create_socket(const std::string &comm_id, const int fd); + static CSocket *create_socket(const std::string &comm_id, const int fd,bool ip_v6=false); /** * \brief Function to actually open the device * @@ -300,7 +305,7 @@ class CSocket : public CComm * unique identifier for all the threads and events of the * class. */ - CSocket(const std::string &comm_id,socket_type_t type=socket_tcp); + CSocket(const std::string &comm_id,socket_type_t type=socket_tcp, bool ip_v6=false); /** * \brief Function to get the name of Connection Closed Event * diff --git a/include/sockets/socketclient.h b/include/sockets/socketclient.h index 741a876b87c6963def291e63e341f918a1bd2f46..583999b2bf14c722180ccb6e46bb2cd244aa067e 100644 --- a/include/sockets/socketclient.h +++ b/include/sockets/socketclient.h @@ -110,7 +110,7 @@ class CSocketClient : public CSocket * it is important that a single identifier is not used more * than once. */ - CSocketClient(const std::string &sock_id); + CSocketClient(const std::string &sock_id,bool ip_v6=false); /** * \brief function to return the remote server port * diff --git a/include/sockets/socketserver.h b/include/sockets/socketserver.h index 228b23b9aab438a6f91cb6dcfe909279a7a6bc12..744e853efadad1f9049ab7f37f25c1744dedc465 100644 --- a/include/sockets/socketserver.h +++ b/include/sockets/socketserver.h @@ -448,7 +448,7 @@ class CSocketServer : public CSocket * must have a different one, since it is used to generate the * unique identifier for both threads and events. */ - CSocketServer(const std::string &sock_id); + CSocketServer(const std::string &sock_id,bool ip_v6=false); /** * \brief function to set the maximum number of simultaneous clients * diff --git a/include/sockets/socketudp.h b/include/sockets/socketudp.h index 2f669829117bb94c1d00f9ac7ad93ec42d3bdc5d..3022bb80f4a2b553437ffc0457c0d96ebfe95dc5 100755 --- a/include/sockets/socketudp.h +++ b/include/sockets/socketudp.h @@ -85,7 +85,7 @@ class CSocketUDP : public CSocket */ virtual void hard_close(void); public: - CSocketUDP(const std::string &sock_id); + CSocketUDP(const std::string &sock_id,bool ip_v6=false); std::string add_client(std::string &ip); int write_to(std::string &ip,int port,unsigned char *data,int len); int read_from(std::string &ip, unsigned char *data, int len); diff --git a/src/examples/test_simple_client.cpp b/src/examples/test_simple_client.cpp index 92904e0643f81734ba0d525380faaf33f0cd5d0a..f80c390ba61f1b40afedd0c021f4a5b31972b1d6 100644 --- a/src/examples/test_simple_client.cpp +++ b/src/examples/test_simple_client.cpp @@ -1,13 +1,13 @@ #include "socketclient.h" #include "socketexceptions.h" -std::string server_ip="192.168.100.97"; +std::string server_ip="fc94:cbd6:6e7b:4c97:fac6:5c5f:34f7:da11"; int server_port=6653; int main(int argc,char *argv[]) { TSocket_info info; - CSocketClient client("client"); + CSocketClient client("client",true); unsigned char msg[5]="hola",answer[5]; try{ diff --git a/src/examples/test_simple_client_udp_rx.cpp b/src/examples/test_simple_client_udp_rx.cpp index 120437ce963ffb7d7ede19a2b854f592d6a215c2..3d872e5e50f320c06c90ee07aa20ee8b40d4d549 100755 --- a/src/examples/test_simple_client_udp_rx.cpp +++ b/src/examples/test_simple_client_udp_rx.cpp @@ -1,7 +1,7 @@ #include "socketudp.h" #include "socketexceptions.h" -std::string server_ip="192.168.100.97"; +std::string server_ip="fc94:cbd6:6e7b:4c97:fac6:5c5f:34f7:da11"; int server_port=49152; int main(int argc,char *argv[]) @@ -9,7 +9,7 @@ int main(int argc,char *argv[]) CEventServer *event_server=CEventServer::instance(); int num=0; TSocket_info info; - CSocketUDP client("client"); + CSocketUDP client("client",true); unsigned char msg[5]; std::list<std::string> events; diff --git a/src/examples/test_simple_client_udp_tx.cpp b/src/examples/test_simple_client_udp_tx.cpp index 128a400836541f25e7abb21c524a9fddf802e53a..0d0aa1d86496a4009bf2f75088c52168bcdd6086 100755 --- a/src/examples/test_simple_client_udp_tx.cpp +++ b/src/examples/test_simple_client_udp_tx.cpp @@ -1,13 +1,13 @@ #include "socketudp.h" #include "socketexceptions.h" -std::string server_ip="192.168.100.97"; +std::string server_ip="fc94:ffb7:3369:2720:4ee2:68bb:5801:e7f6"; int server_port=49152; int main(int argc,char *argv[]) { TSocket_info info; - CSocketUDP client("client"); + CSocketUDP client("client",true); unsigned char msg[5]="hola"; try{ diff --git a/src/examples/test_simple_server.cpp b/src/examples/test_simple_server.cpp index aa2f09bb84ccff4e539dc73ac4e54dfc1aa2db83..94ba5ca2d81da03a09ba1502db53d7e7bcefd616 100644 --- a/src/examples/test_simple_server.cpp +++ b/src/examples/test_simple_server.cpp @@ -2,14 +2,14 @@ #include "socketserver.h" #include "eventserver.h" -std::string server_IP_address="192.168.100.97"; +std::string server_IP_address="fc94:cbd6:6e7b:4c97:fac6:5c5f:34f7:da11"; int server_port=6653; int num_listen=1; int main(int argc,char *argv[]) { CEventServer *event_server=CEventServer::instance(); - CSocketServer server("server"); + CSocketServer server("server",true); std::list<std::string> con_events,client_events; TSocket_info sock_info; unsigned char *data; diff --git a/src/sockets/socket.cpp b/src/sockets/socket.cpp index a73494c8444f016dc52f2aa07def774212570d12..fe9d8738fa4e428d01d0a7d308916f193fba56a6 100644 --- a/src/sockets/socket.cpp +++ b/src/sockets/socket.cpp @@ -3,7 +3,7 @@ #include <string.h> #include "errno.h" -CSocket::CSocket(const std::string &comm_id,socket_type_t type) : CComm(comm_id) +CSocket::CSocket(const std::string &comm_id,socket_type_t type,bool ip_v6) : CComm(comm_id) { this->connection_closed_event.clear(); this->connection_closed_event+=comm_id; @@ -11,9 +11,10 @@ CSocket::CSocket(const std::string &comm_id,socket_type_t type) : CComm(comm_id) this->event_server->create_event(this->connection_closed_event); this->cloned=false; this->type=type; + this->ip_v6=ip_v6; } -CSocket::CSocket(const std::string &comm_id,const int fd) : CComm(comm_id) +CSocket::CSocket(const std::string &comm_id,const int fd,bool ip_v6) : CComm(comm_id) { if(fd<0) { @@ -28,14 +29,15 @@ CSocket::CSocket(const std::string &comm_id,const int fd) : CComm(comm_id) this->event_server->create_event(this->connection_closed_event); this->cloned=true; this->socket_fd=fd; + this->ip_v6=ip_v6; } } -CSocket *CSocket::create_socket(const std::string &comm_id, const int fd) +CSocket *CSocket::create_socket(const std::string &comm_id, const int fd,bool ip_v6) { CSocket *new_socket; - new_socket=new CSocket(comm_id,fd); + new_socket=new CSocket(comm_id,fd,ip_v6); return new_socket; } @@ -48,13 +50,17 @@ std::string CSocket::get_connection_closed_event(void) void CSocket::hard_open(void *comm_dev) { int yes=1; + int domain; if(!this->cloned) { + if(this->ip_v6) + domain=AF_INET6; + else + domain=AF_INET; if(this->type==socket_tcp) - //if((this->socket_fd=socket(AF_INET,SOCK_DGRAM,0))<0) { - if((this->socket_fd=socket(AF_INET,SOCK_STREAM,0))<0) + if((this->socket_fd=socket(domain,SOCK_STREAM,0))<0) { /* handle exceptions */ throw CSocketException(_HERE_,"Error opening socket", this->comm_id); @@ -62,7 +68,7 @@ void CSocket::hard_open(void *comm_dev) } else { - if((this->socket_fd=socket(AF_INET,SOCK_DGRAM,0))<0) + if((this->socket_fd=socket(domain,SOCK_DGRAM,0))<0) { /* handle exceptions */ throw CSocketException(_HERE_,"Error opening socket", this->comm_id); diff --git a/src/sockets/socketclient.cpp b/src/sockets/socketclient.cpp index dc25cbcba860763f8fd1c115635854fa6ba11268..0371669ce8f93640140bfae87b26bb79b64f1a3d 100644 --- a/src/sockets/socketclient.cpp +++ b/src/sockets/socketclient.cpp @@ -2,7 +2,7 @@ #include "socketexceptions.h" #include <string.h> -CSocketClient::CSocketClient(const std::string &sock_id) : CSocket(sock_id,socket_tcp) +CSocketClient::CSocketClient(const std::string &sock_id,bool ip_v6) : CSocket(sock_id,socket_tcp,ip_v6) { this->connected=false; this->remote.address.clear(); @@ -20,34 +20,67 @@ void CSocketClient::hard_close(void) void CSocketClient::hard_open(void *comm_dev) { TSocket_info *remote=(TSocket_info *)comm_dev; - sockaddr_in sock; CSocket::hard_open(NULL); - memset(&sock,0,sizeof(sock)); - sock.sin_family=AF_INET; - if(inet_aton(remote->address.c_str(),&sock.sin_addr)==0) + if(this->ip_v6) { - /* handle exceptions */ - throw CSocketException(_HERE_,"Impossible to convert IP address",this->comm_id); + sockaddr_in6 sock; + memset(&sock,0,sizeof(sock)); + sock.sin6_family=AF_INET6; + if(inet_pton(AF_INET6,remote->address.c_str(),&sock.sin6_addr)==0) + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Impossible to convert IP address",this->comm_id); + } + else + { + sock.sin6_port=htons(remote->port); + if((::connect(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock)))<0) + { + /* handle exceptions */ + if(errno==ECONNREFUSED) + throw CSocketNoConnectionException(_HERE_,"Nobody listening",this->comm_id); + else + throw CSocketException(_HERE_, "Error with connect function", this->comm_id); + } + else + { + this->connected=true; + this->remote.port=remote->port; + this->remote.address=remote->address; + } + } } else { - sock.sin_port=htons(remote->port); - if((::connect(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock)))<0) + sockaddr_in sock; + memset(&sock,0,sizeof(sock)); + sock.sin_family=AF_INET; + if(inet_pton(AF_INET,remote->address.c_str(),&sock.sin_addr)==0) { /* handle exceptions */ - if(errno==ECONNREFUSED) - throw CSocketNoConnectionException(_HERE_,"Nobody listening",this->comm_id); - else - throw CSocketException(_HERE_, "Error with connect function", this->comm_id); + throw CSocketException(_HERE_,"Impossible to convert IP address",this->comm_id); } else { - this->connected=true; - this->remote.port=remote->port; - this->remote.address=remote->address; + sock.sin_port=htons(remote->port); + if((::connect(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock)))<0) + { + /* handle exceptions */ + if(errno==ECONNREFUSED) + throw CSocketNoConnectionException(_HERE_,"Nobody listening",this->comm_id); + else + throw CSocketException(_HERE_, "Error with connect function", this->comm_id); + } + else + { + this->connected=true; + this->remote.port=remote->port; + this->remote.address=remote->address; + } } } + } int CSocketClient::get_remote_port(void) diff --git a/src/sockets/socketserver.cpp b/src/sockets/socketserver.cpp index 599e8d0355263ca333d8b27be6a113d10f14788b..76d0c2b8c21bb94d1cb67b458a1aee18f07b1008 100644 --- a/src/sockets/socketserver.cpp +++ b/src/sockets/socketserver.cpp @@ -9,7 +9,7 @@ int CSocketServer::counter=0; -CSocketServer::CSocketServer(const std::string &sock_id) : CSocket(sock_id) +CSocketServer::CSocketServer(const std::string &sock_id,bool ip_v6) : CSocket(sock_id,socket_tcp,ip_v6) { this->current_clients=0; this->max_clients=0; @@ -44,58 +44,116 @@ CSocketServer::CSocketServer(const std::string &sock_id) : CSocket(sock_id) void CSocketServer::hard_open(void *comm_dev) { TSocket_info *info=(TSocket_info *)comm_dev; - sockaddr_in sock; - memset(&sock,0,sizeof(sock)); - CSocket::hard_open(); - if(comm_dev==NULL) + if(this->ip_v6) { - /* handle exceptions */ - throw CSocketException(_HERE_,"Invalid server information",this->comm_id); - } - else - { - // set non-blocking operation - if(fcntl(this->socket_fd,F_SETFL,O_NONBLOCK)<0) + sockaddr_in6 sock; + memset(&sock,0,sizeof(sock)); + CSocket::hard_open(); + if(comm_dev==NULL) { /* handle exceptions */ - std::cout << "error" << std::endl; + throw CSocketException(_HERE_,"Invalid server information",this->comm_id); } else { - if(this->state==server_created) + // set non-blocking operation + if(fcntl(this->socket_fd,F_SETFL,O_NONBLOCK)<0) { - sock.sin_family=AF_INET; - if(inet_aton(info->address.c_str(),&sock.sin_addr)==0) - { - /* handle exceptions */ - throw CSocketException(_HERE_,"Impossible to convert IP address",this->comm_id); - } - else + /* handle exceptions */ + std::cout << "error" << std::endl; + } + else + { + if(this->state==server_created) { - sock.sin_port=htons(info->port); - if(::bind(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock))<0) + sock.sin6_family=AF_INET6; + if(inet_pton(AF_INET6,info->address.c_str(),&sock.sin6_addr)==0) { /* handle exceptions */ - throw CSocketException(_HERE_,"Impossible to bind the socket to the desired IP address and port.",this->comm_id); - } + throw CSocketException(_HERE_,"Impossible to convert IP address",this->comm_id); + } else { - this->server_access.enter(); - this->state=server_binded; - this->info.port=info->port; - this->info.address=info->address; - this->server_access.exit(); + sock.sin6_port=htons(info->port); + if(::bind(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock))<0) + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Impossible to bind the socket to the desired IP address and port.",this->comm_id); + } + else + { + this->server_access.enter(); + this->state=server_binded; + this->info.port=info->port; + this->info.address=info->address; + this->server_access.exit(); + } } } + else + { + /* handle exceptions */ + throw CSocketException(_HERE_,"The server is not created.",this->comm_id); + } + } + } + } + else + { + sockaddr_in sock; + memset(&sock,0,sizeof(sock)); + CSocket::hard_open(); + if(comm_dev==NULL) + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Invalid server information",this->comm_id); + } + else + { + // set non-blocking operation + if(fcntl(this->socket_fd,F_SETFL,O_NONBLOCK)<0) + { + /* handle exceptions */ + std::cout << "error" << std::endl; } else { - /* handle exceptions */ - throw CSocketException(_HERE_,"The server is not created.",this->comm_id); + if(this->state==server_created) + { + sock.sin_family=AF_INET; + if(inet_pton(AF_INET,info->address.c_str(),&sock.sin_addr)==0) + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Impossible to convert IP address",this->comm_id); + } + else + { + sock.sin_port=htons(info->port); + if(::bind(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock))<0) + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Impossible to bind the socket to the desired IP address and port.",this->comm_id); + } + else + { + this->server_access.enter(); + this->state=server_binded; + this->info.port=info->port; + this->info.address=info->address; + this->server_access.exit(); + } + } + } + else + { + /* handle exceptions */ + throw CSocketException(_HERE_,"The server is not created.",this->comm_id); + } } } } + } void CSocketServer::hard_config(void *config) { @@ -338,7 +396,6 @@ TClient_info *CSocketServer::get_new_client(void) void CSocketServer::free_client(TClient_info *info) { std::list<TClient_info_int *>:: iterator it; - sockaddr_in sock; this->server_access.enter(); for(it=this->client_list.begin();it!=this->client_list.end();it++) @@ -353,14 +410,30 @@ void CSocketServer::free_client(TClient_info *info) delete info; if(this->socket_fd==-1) { - memset(&sock,0,sizeof(sock)); - sock.sin_family=AF_INET; - inet_aton(this->info.address.c_str(),&sock.sin_addr); - sock.sin_port=htons(this->info.port); - this->CSocket::hard_open(); - ::bind(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock)); - ::listen(this->socket_fd,1); - this->state=server_on; + if(this->ip_v6) + { + sockaddr_in6 sock; + memset(&sock,0,sizeof(sock)); + sock.sin6_family=AF_INET6; + inet_pton(AF_INET6,this->info.address.c_str(),&sock.sin6_addr); + sock.sin6_port=htons(this->info.port); + this->CSocket::hard_open(); + ::bind(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock)); + ::listen(this->socket_fd,1); + this->state=server_on; + } + else + { + sockaddr_in sock; + memset(&sock,0,sizeof(sock)); + sock.sin_family=AF_INET; + inet_pton(AF_INET,this->info.address.c_str(),&sock.sin_addr); + sock.sin_port=htons(this->info.port); + this->CSocket::hard_open(); + ::bind(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock)); + ::listen(this->socket_fd,1); + this->state=server_on; + } } this->server_access.exit(); return; @@ -376,7 +449,6 @@ void *CSocketServer::connect_thread(void *param) TClient_info_int *client_info_int; std::stringstream sock_id; TClient_info *client_info; - struct sockaddr_in client; int new_fd,len=0; bool end=false; @@ -386,57 +458,118 @@ void *CSocketServer::connect_thread(void *param) { server->server_access.enter(); try{ - len=sizeof(client); - server->server_access.exit(); - if((new_fd=::accept(server->socket_fd,(struct sockaddr *)&client,(socklen_t *)&len))<0) + if(server->ip_v6) { - if(errno==EWOULDBLOCK) + struct sockaddr_in6 client; + char addr[128]; + len=sizeof(client); + server->server_access.exit(); + if((new_fd=::accept(server->socket_fd,(struct sockaddr *)&client,(socklen_t *)&len))<0) { - if(server->event_server->event_is_set(server->finish_connect_thread_event_id)) - end=true; + if(errno==EWOULDBLOCK) + { + if(server->event_server->event_is_set(server->finish_connect_thread_event_id)) + end=true; + else + usleep(100000); + } else - usleep(100000); + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Unexpected error while accepting new connections.",server->comm_id); + } } else - { - /* handle exceptions */ - throw CSocketException(_HERE_,"Unexpected error while accepting new connections.",server->comm_id); + { + server->server_access.enter(); + server->counter++; + sock_id.str(""); + sock_id << "client_socket_" << server->counter; + // initialize the internal client info + client_info_int=new TClient_info_int; + client_info_int->socket=CSocket::create_socket(sock_id.str(),new_fd,server->ip_v6); + client_info_int->socket->open(NULL); + client_info_int->socket->config(NULL); + client_info_int->client_id=sock_id.str(); + client_info_int->disconnect_event_id=sock_id.str()+"_disconnect"; + server->event_server->create_event(client_info_int->disconnect_event_id); + // initialize the external client info + client_info=new TClient_info; + client_info->client_id=sock_id.str(); + client_info->IP=inet_ntop(AF_INET6,client.sin6_addr.s6_addr,addr,sizeof(addr)); + client_info->port=(int)(ntohs(client.sin6_port)); + client_info->disconnect_event_id=client_info_int->disconnect_event_id; + client_info->rx_event_id=client_info_int->socket->get_rx_event_id(); + // signal the connection of a new client + server->new_clients.push(client_info); + server->client_list.push_back(client_info_int); + server->current_clients++; + server->event_server->set_event(server->new_connection_event_id); + server->event_server->set_event(server->update_list_event_id); + if(server->current_clients==server->max_clients) + { + server->CSocket::hard_close(); + server->state=server_created; + } + server->server_access.exit(); } } else { - server->server_access.enter(); - server->counter++; - sock_id.str(""); - sock_id << "client_socket_" << server->counter; - // initialize the internal client info - client_info_int=new TClient_info_int; - client_info_int->socket=CSocket::create_socket(sock_id.str(),new_fd); - client_info_int->socket->open(NULL); - client_info_int->socket->config(NULL); - client_info_int->client_id=sock_id.str(); - client_info_int->disconnect_event_id=sock_id.str()+"_disconnect"; - server->event_server->create_event(client_info_int->disconnect_event_id); - // initialize the external client info - client_info=new TClient_info; - client_info->client_id=sock_id.str(); - client_info->IP=inet_ntoa(client.sin_addr); - client_info->port=(int)(ntohs(client.sin_port)); - client_info->disconnect_event_id=client_info_int->disconnect_event_id; - client_info->rx_event_id=client_info_int->socket->get_rx_event_id(); - // signal the connection of a new client - server->new_clients.push(client_info); - server->client_list.push_back(client_info_int); - server->current_clients++; - server->event_server->set_event(server->new_connection_event_id); - server->event_server->set_event(server->update_list_event_id); - if(server->current_clients==server->max_clients) + struct sockaddr_in client; + len=sizeof(client); + server->server_access.exit(); + if((new_fd=::accept(server->socket_fd,(struct sockaddr *)&client,(socklen_t *)&len))<0) { - server->CSocket::hard_close(); - server->state=server_created; + if(errno==EWOULDBLOCK) + { + if(server->event_server->event_is_set(server->finish_connect_thread_event_id)) + end=true; + else + usleep(100000); + } + else + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Unexpected error while accepting new connections.",server->comm_id); + } + } + else + { + server->server_access.enter(); + server->counter++; + sock_id.str(""); + sock_id << "client_socket_" << server->counter; + // initialize the internal client info + client_info_int=new TClient_info_int; + client_info_int->socket=CSocket::create_socket(sock_id.str(),new_fd,server->ip_v6); + client_info_int->socket->open(NULL); + client_info_int->socket->config(NULL); + client_info_int->client_id=sock_id.str(); + client_info_int->disconnect_event_id=sock_id.str()+"_disconnect"; + server->event_server->create_event(client_info_int->disconnect_event_id); + // initialize the external client info + client_info=new TClient_info; + client_info->client_id=sock_id.str(); + client_info->IP=inet_ntoa(client.sin_addr); + client_info->port=(int)(ntohs(client.sin_port)); + client_info->disconnect_event_id=client_info_int->disconnect_event_id; + client_info->rx_event_id=client_info_int->socket->get_rx_event_id(); + // signal the connection of a new client + server->new_clients.push(client_info); + server->client_list.push_back(client_info_int); + server->current_clients++; + server->event_server->set_event(server->new_connection_event_id); + server->event_server->set_event(server->update_list_event_id); + if(server->current_clients==server->max_clients) + { + server->CSocket::hard_close(); + server->state=server_created; + } + server->server_access.exit(); } - server->server_access.exit(); } + }catch(CException &e){ server->server_access.exit(); std::cout << e.what() << std::endl; @@ -487,11 +620,9 @@ void *CSocketServer::disconnect_thread(void *param) it_event=events.begin(); it_client=server->client_list.begin(); for(i=0;i<(event_id-2);i++) - { - it_event++; it_client++; - } - it_event++; + for(i=0;i<event_id;i++) + it_event++; if(!server->event_server->event_is_set((*it_client)->disconnect_event_id)) server->event_server->set_event((*it_client)->disconnect_event_id); events.erase(it_event); diff --git a/src/sockets/socketudp.cpp b/src/sockets/socketudp.cpp index 59c9055ed2f1f3e01cb53ed4f6953e72e2a8871e..3460612cc279f83fba537cb5ba5a708c37ab342f 100755 --- a/src/sockets/socketudp.cpp +++ b/src/sockets/socketudp.cpp @@ -1,7 +1,7 @@ #include "socketudp.h" #include "socketexceptions.h" -CSocketUDP::CSocketUDP(const std::string &sock_id) : CSocket(sock_id,socket_udp) +CSocketUDP::CSocketUDP(const std::string &sock_id,bool ip_v6) : CSocket(sock_id,socket_udp,ip_v6) { this->associated_port=-1; this->clients.clear(); @@ -10,49 +10,91 @@ CSocketUDP::CSocketUDP(const std::string &sock_id) : CSocket(sock_id,socket_udp) void CSocketUDP::hard_open(void *comm_dev) { int *port=(int *)comm_dev; - sockaddr_in sock; CSocket::hard_open(NULL); if(port!=NULL) { - memset(&sock,0,sizeof(sock)); - sock.sin_family=AF_INET; - sock.sin_addr.s_addr=htonl(INADDR_ANY); - sock.sin_port=htons(*port); - // bind to the desired IP and port to receive data from - if((::bind(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock)))<0) + if(this->ip_v6) { - /* handle exceptions */ - throw CSocketException(_HERE_, "Error with connect function", this->comm_id); + sockaddr_in6 sock; + memset(&sock,0,sizeof(sock)); + sock.sin6_family=AF_INET6; + sock.sin6_addr=in6addr_any; + sock.sin6_port=htons(*port); + // bind to the desired IP and port to receive data from + if((::bind(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock)))<0) + { + /* handle exceptions */ + throw CSocketException(_HERE_, "Error with connect function", this->comm_id); + } + else + this->associated_port=*port; } else - this->associated_port=*port; + { + sockaddr_in sock; + memset(&sock,0,sizeof(sock)); + sock.sin_family=AF_INET; + sock.sin_addr.s_addr=htonl(INADDR_ANY); + sock.sin_port=htons(*port); + // bind to the desired IP and port to receive data from + if((::bind(this->socket_fd,(struct sockaddr *)&sock,sizeof(sock)))<0) + { + /* handle exceptions */ + throw CSocketException(_HERE_, "Error with connect function", this->comm_id); + } + else + this->associated_port=*port; + } + } } int CSocketUDP::hard_read(unsigned char *data, int len) { CEventServer *event_server=CEventServer::instance(); + char addr[128]; unsigned int i=0; - struct sockaddr_in sock; - socklen_t sock_len=sizeof(sock); int read=0; - sock.sin_family=AF_INET; - if((read=recvfrom(this->socket_fd,data,len,0,(struct sockaddr *)&sock,&sock_len))<0) + if(this->ip_v6) { - /* handle exceptions */ - throw CSocketException(_HERE_,"Impossible to read from the socket",this->comm_id); + struct sockaddr_in6 sock; + socklen_t sock_len=sizeof(sock); + sock.sin6_family=AF_INET6; + if((read=recvfrom(this->socket_fd,data,len,0,(struct sockaddr *)&sock,&sock_len))<0) + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Impossible to read from the socket",this->comm_id); + } + // enqueue the data to the corresponding client + for(i=0;i<this->clients.size();i++) + if(this->clients[i]->ip_address==std::string(inet_ntop(AF_INET6,sock.sin6_addr.s6_addr,addr,sizeof(addr)))) + { + this->clients[i]->data_queue.write(data,len); + if(!event_server->event_is_set(this->clients[i]->new_data_avail_event_id)) + event_server->set_event(this->clients[i]->new_data_avail_event_id); + } } - // enqueue the data to the corresponding client - for(i=0;i<this->clients.size();i++) - if(this->clients[i]->ip_address==std::string(inet_ntoa(sock.sin_addr))) + else + { + struct sockaddr_in sock; + socklen_t sock_len=sizeof(sock); + sock.sin_family=AF_INET; + if((read=recvfrom(this->socket_fd,data,len,0,(struct sockaddr *)&sock,&sock_len))<0) { - this->clients[i]->data_queue.write(data,len); - if(!event_server->event_is_set(this->clients[i]->new_data_avail_event_id)) - event_server->set_event(this->clients[i]->new_data_avail_event_id); + /* handle exceptions */ + throw CSocketException(_HERE_,"Impossible to read from the socket",this->comm_id); } - + // enqueue the data to the corresponding client + for(i=0;i<this->clients.size();i++) + if(this->clients[i]->ip_address==std::string(inet_ntoa(sock.sin_addr))) + { + this->clients[i]->data_queue.write(data,len); + if(!event_server->event_is_set(this->clients[i]->new_data_avail_event_id)) + event_server->set_event(this->clients[i]->new_data_avail_event_id); + } + } return read; } @@ -74,26 +116,50 @@ void CSocketUDP::hard_close(void) int CSocketUDP::write_to(std::string &ip,int port,unsigned char *data,int len) { - sockaddr_in sock; int written=0; - memset(&sock,0,sizeof(sock)); - sock.sin_family=AF_INET; - if(inet_aton(ip.c_str(),&sock.sin_addr)==0) + if(this->ip_v6) { - /* handle exceptions */ - throw CSocketException(_HERE_,"Impossible to convert IP address",this->comm_id); + sockaddr_in6 sock; + memset(&sock,0,sizeof(sock)); + sock.sin6_family=AF_INET6; + if(inet_pton(AF_INET6,ip.c_str(),&sock.sin6_addr)==0) + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Impossible to convert IP address",this->comm_id); + } + else + { + sock.sin6_port=htons(port); + if((written=sendto(this->socket_fd,data,len,0,(struct sockaddr *)&sock,sizeof(sock)))<0) + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Impossible to send data to the desired IP and port",this->comm_id); + } + } } else { - sock.sin_port=htons(port); - if((written=sendto(this->socket_fd,data,len,0,(struct sockaddr *)&sock,sizeof(sock)))<0) + sockaddr_in sock; + memset(&sock,0,sizeof(sock)); + sock.sin_family=AF_INET; + if(inet_pton(AF_INET,ip.c_str(),&sock.sin_addr)==0) { /* handle exceptions */ - throw CSocketException(_HERE_,"Impossible to send data to the desired IP and port",this->comm_id); + throw CSocketException(_HERE_,"Impossible to convert IP address",this->comm_id); + } + else + { + sock.sin_port=htons(port); + if((written=sendto(this->socket_fd,data,len,0,(struct sockaddr *)&sock,sizeof(sock)))<0) + { + /* handle exceptions */ + throw CSocketException(_HERE_,"Impossible to send data to the desired IP and port",this->comm_id); + } + } - return written; } + return written; } int CSocketUDP::read_from(std::string &ip, unsigned char *data, int len)