Updated/added Socket::UDPConnection documentation, added support for binding to a port and for receiving data.
This commit is contained in:
		
							parent
							
								
									773234f231
								
							
						
					
					
						commit
						7f1b28bd6f
					
				
					 2 changed files with 105 additions and 20 deletions
				
			
		|  | @ -899,7 +899,9 @@ int Socket::Server::getSocket(){ | |||
| } | ||||
| 
 | ||||
| /// Create a new UDP Socket.
 | ||||
| /// \param nonblock Whether the socket should be nonblocking. 
 | ||||
| /// Will attempt to create an IPv6 UDP socket, on fail try a IPV4 UDP socket.
 | ||||
| /// If both fail, prints an DLVL_FAIL debug message.
 | ||||
| /// \param nonblock Whether the socket should be nonblocking.
 | ||||
| Socket::UDPConnection::UDPConnection(bool nonblock){ | ||||
|   sock = socket(AF_INET6, SOCK_DGRAM, 0); | ||||
|   if (sock == -1){ | ||||
|  | @ -912,11 +914,16 @@ Socket::UDPConnection::UDPConnection(bool nonblock){ | |||
|   down = 0; | ||||
|   destAddr = 0; | ||||
|   destAddr_size = 0; | ||||
|   data = 0; | ||||
|   data_size = 0; | ||||
|   data_len = 0; | ||||
|   if (nonblock){ | ||||
|     setBlocking(!nonblock); | ||||
|   } | ||||
| } //Socket::UDPConnection UDP Contructor
 | ||||
| 
 | ||||
| /// Copies a UDP socket, re-allocating local copies of any needed structures.
 | ||||
| /// The data/data_size/data_len variables are *not* copied over.
 | ||||
| Socket::UDPConnection::UDPConnection(const UDPConnection & o){ | ||||
|   sock = socket(AF_INET6, SOCK_DGRAM, 0); | ||||
|   if (sock == -1){ | ||||
|  | @ -936,8 +943,12 @@ Socket::UDPConnection::UDPConnection(const UDPConnection & o){ | |||
|     destAddr = 0; | ||||
|     destAddr_size = 0; | ||||
|   } | ||||
|   data = 0; | ||||
|   data_size = 0; | ||||
|   data_len = 0; | ||||
| } | ||||
| 
 | ||||
| /// Closes the UDP socket, cleans up any memory allocated by the socket.
 | ||||
| Socket::UDPConnection::~UDPConnection(){ | ||||
|   if (sock != -1){ | ||||
|     errno = EINTR; | ||||
|  | @ -949,9 +960,19 @@ Socket::UDPConnection::~UDPConnection(){ | |||
|     free(destAddr); | ||||
|     destAddr = 0; | ||||
|   } | ||||
|   if (data){ | ||||
|     free(data); | ||||
|     data = 0; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// Stores the properties of the reiving end of this UDP socket.
 | ||||
| /// This will be the receiving end for all SendNow calls.
 | ||||
| void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){ | ||||
|   if (destAddr){ | ||||
|     free(destAddr); | ||||
|     destAddr = 0; | ||||
|   } | ||||
|   destAddr = malloc(sizeof(struct sockaddr_in6)); | ||||
|   if (destAddr){ | ||||
|     destAddr_size = sizeof(struct sockaddr_in6); | ||||
|  | @ -979,27 +1000,87 @@ void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){ | |||
|   DEBUG_MSG(DLVL_FAIL, "Could not set destination for UDP socket: %s:%d", destIp.c_str(), port); | ||||
| }//Socket::UDPConnection SetDestination
 | ||||
| 
 | ||||
| /// Sets the socket to be blocking if the parameters is true.
 | ||||
| /// Sets the socket to be non-blocking otherwise.
 | ||||
| void Socket::UDPConnection::setBlocking(bool blocking){ | ||||
|   if (sock >= 0){ | ||||
|     setFDBlocking(sock, blocking); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void Socket::UDPConnection::SendNow(const std::string & data){ | ||||
|   SendNow(data.c_str(), data.size()); | ||||
| /// Sends a UDP datagram using the buffer sdata.
 | ||||
| /// This function simply calls SendNow(const char*, size_t)
 | ||||
| void Socket::UDPConnection::SendNow(const std::string & sdata){ | ||||
|   SendNow(sdata.c_str(), sdata.size()); | ||||
| } | ||||
| 
 | ||||
| void Socket::UDPConnection::SendNow(const char* data){ | ||||
|   int len = strlen(data); | ||||
|   SendNow(data, len); | ||||
| /// Sends a UDP datagram using the buffer sdata.
 | ||||
| /// sdata is required to be NULL-terminated.
 | ||||
| /// This function simply calls SendNow(const char*, size_t)
 | ||||
| void Socket::UDPConnection::SendNow(const char* sdata){ | ||||
|   int len = strlen(sdata); | ||||
|   SendNow(sdata, len); | ||||
| } | ||||
| 
 | ||||
| void Socket::UDPConnection::SendNow(const char * data, size_t len){ | ||||
| /// Sends a UDP datagram using the buffer sdata of length len.
 | ||||
| /// Does not do anything if len < 1.
 | ||||
| /// Prints an DLVL_FAIL level debug message if sending failed.
 | ||||
| void Socket::UDPConnection::SendNow(const char * sdata, size_t len){ | ||||
|   if (len < 1){return;} | ||||
|   int r = sendto(sock, data, len, 0, (sockaddr*)destAddr, destAddr_size); | ||||
|   int r = sendto(sock, sdata, len, 0, (sockaddr*)destAddr, destAddr_size); | ||||
|   if (r > 0){ | ||||
|     up += r; | ||||
|   }else{ | ||||
|     DEBUG_MSG(DLVL_FAIL, "Could not send UDP data through %d: %s", sock, strerror(errno)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /// Bind to a port number, returning the bound port.
 | ||||
| /// Attempts to bind over IPv6 first.
 | ||||
| /// If it fails, attempts to bind over IPv4.
 | ||||
| /// If that fails too, gives up and returns zero.
 | ||||
| /// Prints a debug message at DLVL_FAIL level if binding failed.
 | ||||
| /// \return Actually bound port number, or zero on error.
 | ||||
| int Socket::UDPConnection::bind(int port){ | ||||
|   struct sockaddr_in6 s6; | ||||
|   s6.sin6_family = AF_INET6; | ||||
|   s6.sin6_addr = in6addr_any; | ||||
|   if (port){s6.sin6_port = htons(port);} | ||||
|   int r = ::bind(sock, (sockaddr*)&s6, sizeof(s6)); | ||||
|   if (r == 0){return ntohs(s6.sin6_port);} | ||||
|    | ||||
|   struct sockaddr_in s4; | ||||
|   s4.sin_family = AF_INET; | ||||
|   s4.sin_addr.s_addr = INADDR_ANY; | ||||
|   if (port){s4.sin_port = htons(port);} | ||||
|   r = ::bind(sock, (sockaddr*)&s4, sizeof(s4)); | ||||
|   if (r == 0){return ntohs(s4.sin_port);} | ||||
|    | ||||
|   DEBUG_MSG(DLVL_FAIL, "Could not bind UDP socket to port %d", port); | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| /// Attempt to receive a UDP packet.
 | ||||
| /// This will automatically allocate or resize the internal data buffer if needed.
 | ||||
| /// If a packet is received, it will be placed in the "data" member, with it's length in "data_len".
 | ||||
| /// \return True if a packet was received, false otherwise.
 | ||||
| bool Socket::UDPConnection::Receive(){ | ||||
|   int r = recvfrom(sock, data, data_size, MSG_PEEK | MSG_TRUNC, 0, 0); | ||||
|   if (data_size < (unsigned int)r){ | ||||
|     data = (char*)realloc(data, r); | ||||
|     if (data){ | ||||
|       data_size = r; | ||||
|     }else{ | ||||
|       data_size = 0; | ||||
|     } | ||||
|   } | ||||
|   r = recvfrom(sock, data, data_size, 0, 0, 0); | ||||
|   if (r > 0){ | ||||
|     down += r; | ||||
|     data_len = r; | ||||
|     return true; | ||||
|   }else{ | ||||
|     data_len = 0; | ||||
|     return false; | ||||
|   } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										28
									
								
								lib/socket.h
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								lib/socket.h
									
										
									
									
									
								
							|  | @ -123,20 +123,24 @@ namespace Socket { | |||
|     private: | ||||
|       int sock; ///< Internally saved socket number.
 | ||||
|       std::string remotehost;///< Stores remote host address
 | ||||
|       void * destAddr; | ||||
|       unsigned int destAddr_size; | ||||
|       unsigned int up; | ||||
|       unsigned int down; | ||||
|       void * destAddr;///< Destination address pointer.
 | ||||
|       unsigned int destAddr_size;///< Size of the destination address pointer.
 | ||||
|       unsigned int up;///< Amount of bytes transferred up.
 | ||||
|       unsigned int down;///< Amount of bytes transferred down.
 | ||||
|       unsigned int data_size;///< The size in bytes of the allocated space in the data pointer.
 | ||||
|     public: | ||||
|       UDPConnection(const UDPConnection & o); ///< Copy constructor
 | ||||
|       UDPConnection(bool nonblock = false); ///< Create new UDP socket
 | ||||
|       char * data;///< Holds the last received packet.
 | ||||
|       unsigned int data_len; ///< The size in bytes of the last received packet.
 | ||||
|       UDPConnection(const UDPConnection & o); | ||||
|       UDPConnection(bool nonblock = false); | ||||
|       ~UDPConnection(); | ||||
|       void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
 | ||||
|       void SetDestination(std::string hostname, uint32_t port); ///< Sets the hostname and port destination for this UDP socket.
 | ||||
|       void Close();///< Closes the local socket
 | ||||
|       void SendNow(const std::string & data); ///< Will not buffer anything but always send right away. Blocks.
 | ||||
|       void SendNow(const char * data); ///< Will not buffer anything but always send right away. Blocks.
 | ||||
|       void SendNow(const char * data, size_t len); ///< Will not buffer anything but always send right away. Blocks.
 | ||||
|       int bind(int port); | ||||
|       void setBlocking(bool blocking); | ||||
|       void SetDestination(std::string hostname, uint32_t port); | ||||
|       bool Receive(); | ||||
|       void SendNow(const std::string & data); | ||||
|       void SendNow(const char * data); | ||||
|       void SendNow(const char * data, size_t len); | ||||
|   }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Thulinma
						Thulinma