diff --git a/src/examples/test_simple_client_udp_rx.cpp b/src/examples/test_simple_client_udp_rx.cpp
index 220d6de5cde22c9b7346ecc61578963de1ee1bbb..120437ce963ffb7d7ede19a2b854f592d6a215c2 100755
--- a/src/examples/test_simple_client_udp_rx.cpp
+++ b/src/examples/test_simple_client_udp_rx.cpp
@@ -2,26 +2,30 @@
 #include "socketexceptions.h"
 
 std::string server_ip="192.168.100.97";
-int server_port=6653;
+int server_port=49152;
 
 int main(int argc,char *argv[])
 {
+  CEventServer *event_server=CEventServer::instance();
+  int num=0;
   TSocket_info info;
   CSocketUDP client("client");
-  unsigned char answer[5];
+  unsigned char msg[5];
+  std::list<std::string> events;
 
   try{
     info.address=server_ip;
     info.port=server_port;
-    client.open(&info);
-    client.config(NULL);
+    client.open(&server_port);
+    client.config();
+    events.push_back(client.add_client(server_ip));
     std::cout << "connected." << std::endl;
     while(1)
     {
-      std::cout << "receiving data ..." << std::endl;
-      client.read(answer,5);
-      std::cout << "data received: " << answer << std::endl;
-      sleep(1);
+      event_server->wait_all(events);
+      num=client.get_num_data_from(server_ip);
+      num=client.read_from(server_ip,msg,num);
+      std::cout << msg << "," << num << std::endl;
     }
     std::cout << "closing connection ..." << std::endl;
     client.close();
diff --git a/src/examples/test_simple_client_udp_tx.cpp b/src/examples/test_simple_client_udp_tx.cpp
index 32f5bf06f8884afa183b749195dd5f09c6d6b1e9..128a400836541f25e7abb21c524a9fddf802e53a 100755
--- a/src/examples/test_simple_client_udp_tx.cpp
+++ b/src/examples/test_simple_client_udp_tx.cpp
@@ -2,7 +2,7 @@
 #include "socketexceptions.h"
 
 std::string server_ip="192.168.100.97";
-int server_port=6653;
+int server_port=49152;
 
 int main(int argc,char *argv[])
 {
diff --git a/src/sockets/socket.cpp b/src/sockets/socket.cpp
index 71bf4570fa1e99e089b4c67ceff41a041fa5e93f..e7d97312e8e67073aac2c6c380f74cf7a1e607ec 100644
--- a/src/sockets/socket.cpp
+++ b/src/sockets/socket.cpp
@@ -140,7 +140,6 @@ int CSocket::hard_wait_comm_event(void)
   FD_ZERO(&error_set);
   FD_SET(this->socket_fd,&error_set);
   wait_result=select(max_fd,&receive_set,NULL,&error_set,NULL);
-  std::cout << "new data" << std::endl;
   if(wait_result==-1)
   {
     /* handle exceptions */
diff --git a/src/sockets/socketudp.cpp b/src/sockets/socketudp.cpp
index 8eb2c82ceb06cbae7a66c3915755a7fd3c8163bb..59c9055ed2f1f3e01cb53ed4f6953e72e2a8871e 100755
--- a/src/sockets/socketudp.cpp
+++ b/src/sockets/socketudp.cpp
@@ -3,48 +3,73 @@
 
 CSocketUDP::CSocketUDP(const std::string &sock_id) : CSocket(sock_id,socket_udp)
 {
-  this->receive.port=-1;
-  this->receive.address.clear();
+  this->associated_port=-1;
+  this->clients.clear();
 }
 
 void CSocketUDP::hard_open(void *comm_dev)
 {
-  TSocket_info *remote=(TSocket_info *)comm_dev;
+  int *port=(int *)comm_dev;
   sockaddr_in sock;
 
   CSocket::hard_open(NULL);
-  if(remote!=NULL)
+  if(port!=NULL)
   {
     memset(&sock,0,sizeof(sock));
     sock.sin_family=AF_INET;
-    if(inet_aton(remote->address.c_str(),&sock.sin_addr)==0)
+    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_,"Impossible to convert IP address",this->comm_id);
+      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();
+  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)
+  {
+    /* 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)))
     {
-      sock.sin_port=htons(remote->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->receive.port=remote->port;
-        this->receive.address=remote->address;
-      }
+      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;
 }
 
 void CSocketUDP::hard_close(void)
 {
+  CEventServer *event_server=CEventServer::instance();
+  unsigned int i;
+
   CSocket::hard_close();
-  this->receive.port=-1;
-  this->receive.address.clear();
+  this->associated_port=-1;
+  for(i=0;i<this->clients.size();i++)
+  {
+    event_server->delete_event(this->clients[i]->new_data_avail_event_id);
+    this->clients[i]->new_data_avail_event_id="";
+    this->clients[i]->ip_address="";
+  }
+  this->clients.clear();
 }
 
 int CSocketUDP::write_to(std::string &ip,int port,unsigned char *data,int len)
@@ -70,7 +95,62 @@ int CSocketUDP::write_to(std::string &ip,int port,unsigned char *data,int len)
     return written;
   }
 }
- 
+
+int CSocketUDP::read_from(std::string &ip, unsigned char *data, int len)
+{
+  unsigned int i=0;
+  int read=0;
+  
+  for(i=0;i<this->clients.size();i++)
+  {
+    if(this->clients[i]->ip_address==ip)
+    {
+      read=this->clients[i]->data_queue.read(data,len);
+      return read;
+    }
+  }
+  // handle exceptions
+  throw CSocketException(_HERE_,"The given IP address is not in the allowed list",this->comm_id);
+}
+
+int CSocketUDP::get_num_data_from(std::string &ip)
+{
+  unsigned int i=0;
+
+  for(i=0;i<this->clients.size();i++)
+  {
+    if(this->clients[i]->ip_address==ip)
+    {
+      return this->clients[i]->data_queue.get_num_data();
+    }
+  }
+  // handle exceptions
+  throw CSocketException(_HERE_,"The given IP address is not in the allowed list",this->comm_id);
+}
+
+std::string CSocketUDP::add_client(std::string &ip)
+{
+  CEventServer *event_server=CEventServer::instance();
+  TUDPClient *new_client=new TUDPClient;
+  unsigned int i=0;
+
+  for(i=0;i<this->clients.size();i++)
+  {
+    if(this->clients[i]->ip_address==ip)
+    {
+      /* handle exceptions */
+      throw CSocketException(_HERE_,"The given IP addres is alreasy accepted",this->comm_id);
+    }
+  }
+  // add the new IP address to wait data for
+  new_client->ip_address=ip;
+  new_client->new_data_avail_event_id=ip + "_data_avail_event_id";
+  event_server->create_event(new_client->new_data_avail_event_id);
+  this->clients.push_back(new_client);
+
+  return new_client->new_data_avail_event_id; 
+}
+
 CSocketUDP::~CSocketUDP()
 {
 
diff --git a/src/sockets/socketudp.h b/src/sockets/socketudp.h
index 352f70e613a161c2e85683c3b32d1533d527dacd..2f669829117bb94c1d00f9ac7ad93ec42d3bdc5d 100755
--- a/src/sockets/socketudp.h
+++ b/src/sockets/socketudp.h
@@ -2,11 +2,21 @@
 #define _SOCKETUDP_H_
 
 #include "socket.h"
+#include "cqueue.h"
+#include <vector>
+
+typedef struct
+{
+  std::string ip_address;
+  std::string new_data_avail_event_id;
+  CQueue data_queue;
+}TUDPClient;
 
 class CSocketUDP : public CSocket
 {
   private:
-    TSocket_info receive;
+    int associated_port;
+    std::vector<TUDPClient *> clients;
   protected:
     /**
      * \brief Connect function
@@ -36,6 +46,32 @@ class CSocketUDP : public CSocket
      *                 information on the IP address and port format.
      */
     virtual void hard_open(void *comm_dev=NULL);
+    /**
+     * \brief Function to actually read from the device
+     *
+     * This function is automatically called when the new data received event is 
+     * activated. The read() function from the base class gets data from the 
+     * internal queue, so this function is not used. It must try to read the 
+     * ammount of data specified and store it in the data buffer provided without 
+     * blocking. Also, it must return the number of bytes actually read from the 
+     * devicve, since they may be different than the desired value.
+     *
+     * In case of any error, this function throws a CSocketException exception.
+     *
+     * \param data a reference to the buffer where the received data must be 
+     * copied. The necessary memory for this buffer must be allocated before 
+     * calling this function and have enough size to store all the desired data.
+     * If this buffer is not initialized, the function throws an exception.
+     *
+     * \param len a positive interger that indicates the number of byte to be
+     * read from the communication device. This value must be at most the length 
+     * of the data buffer provided to the function.
+     *
+     * \return an integer with the number of bytes actually read. These number 
+     * coincide with the desired number if there is enough data in the internal 
+     * queue, but it could be smaller if not.
+     */
+    virtual int hard_read(unsigned char *data, int len);
     /**
      * \brief function to close the client socket
      *
@@ -50,7 +86,10 @@ class CSocketUDP : public CSocket
     virtual void hard_close(void);
   public:
     CSocketUDP(const std::string &sock_id);
+    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);
+    int get_num_data_from(std::string &ip);
     ~CSocketUDP();
 };