wip
Dependents: EthernetInterface_vz
Fork of Socket by
Diff: UDPSocket.cpp
- Revision:
- 3:e6474399e057
- Parent:
- 2:b227d242f3c7
- Child:
- 5:300e7ad2dc1d
diff -r b227d242f3c7 -r e6474399e057 UDPSocket.cpp --- a/UDPSocket.cpp Mon Jul 23 11:52:50 2012 +0000 +++ b/UDPSocket.cpp Wed Jul 25 14:59:37 2012 +0000 @@ -22,183 +22,98 @@ using std::memset; -UDPSocket::UDPSocket() : m_sock(-1) -{ -} - -UDPSocket::~UDPSocket() -{ - close(); //Don't want to leak +UDPSocket::UDPSocket() { } -int UDPSocket::bind(int port) -{ - int ret = init(); - if( ret < 0 ) - { - return -1; - } - - struct sockaddr_in localHost; - std::memset(&localHost, 0, sizeof(localHost)); - - localHost.sin_family = AF_INET; - localHost.sin_port = htons(port); - localHost.sin_addr.s_addr = INADDR_ANY; - - ret = ::bind(m_sock, (const struct sockaddr *)&localHost, sizeof(localHost)); - if (ret < 0) - { - close(); - return -1; - } - - return 0; +// Server initialization +int UDPSocket::bind(int port) { + if (init(SOCK_DGRAM) < 0) + return -1; + + struct sockaddr_in localHost; + std::memset(&localHost, 0, sizeof(localHost)); + + localHost.sin_family = AF_INET; + localHost.sin_port = htons(port); + localHost.sin_addr.s_addr = INADDR_ANY; + + if (lwip_bind(_sock_fd, (const struct sockaddr *) &localHost, sizeof(localHost)) < 0) { + close(); + return -1; + } + + return 0; } // -1 if unsuccessful, else number of bytes written -int UDPSocket::sendTo(char* data, int length, char* host, int port, int timeout) -{ - if( m_sock < 0 ) - { - return -1; - } - - struct sockaddr_in remoteHost; - - //Populate m_remoteHost - std::memset(&remoteHost, 0, sizeof(struct sockaddr_in)); - - //Resolve DNS address or populate hard-coded IP address - struct hostent *server = ::gethostbyname(host); - if(server == NULL) - { - return -1; //Could not resolve address - } - std::memcpy((char*)&remoteHost.sin_addr.s_addr, (char*)server->h_addr_list[0], server->h_length); - - remoteHost.sin_family = AF_INET; - remoteHost.sin_port = htons(port); - - size_t writtenLen = 0; - struct timeval t_val; //t_val will be decremented on each call to select() - t_val.tv_sec = timeout / 1000; - t_val.tv_usec = (timeout - (t_val.tv_sec * 1000)) * 1000; - while(writtenLen < length) - { - //Wait for socket to be writeable - //Creating FS set - fd_set socksSet; - FD_ZERO(&socksSet); - FD_SET(m_sock, &socksSet); - - int ret = ::select(FD_SETSIZE, NULL, &socksSet, NULL, &t_val); - if(ret <= 0 || !FD_ISSET(m_sock, &socksSet)) - { - return writtenLen; //Timeout -- FIXME should we return -1 or writtenLength ? +int UDPSocket::sendTo(char* data, int length, char* host, int port, int timeout) { + if (_sock_fd < 0) + return -1; + + struct sockaddr_in remoteHost; + + //Populate m_remoteHost + std::memset(&remoteHost, 0, sizeof(struct sockaddr_in)); + + //Resolve DNS address or populate hard-coded IP address + struct hostent *server = ::gethostbyname(host); + if (server == NULL) { + return -1; //Could not resolve address } - - ret = ::sendto(m_sock, data + writtenLen, length - writtenLen, 0, (const struct sockaddr *)&remoteHost, sizeof(remoteHost)); - if( ret > 0) - { - writtenLen += ret; - continue; + std::memcpy((char*) &remoteHost.sin_addr.s_addr, + (char*) server->h_addr_list[0], server->h_length); + + remoteHost.sin_family = AF_INET; + remoteHost.sin_port = htons(port); + + size_t writtenLen = 0; + set_timeout(timeout); + while (writtenLen < length) { + //Wait for socket to be writeable + //Creating FS set + if (wait_writable() != 0) + return writtenLen; //Timeout -- FIXME should we return -1 or writtenLength ? + + int ret = lwip_sendto(_sock_fd, data + writtenLen, length - writtenLen, 0, + (const struct sockaddr *) &remoteHost, sizeof(remoteHost)); + if (ret > 0) { + writtenLen += ret; + } else if (ret == 0) { + return writtenLen; //Connection was closed by server -- FIXME how do we signal that the connection was closed ? + } else { + return -1; //Connnection error + } } - else if( ret == 0 ) - { - return writtenLen; //Connection was closed by server -- FIXME how do we signal that the connection was closed ? - } - else - { - return -1; //Connnection error - } - } - - return writtenLen; + + return writtenLen; } // -1 if unsuccessful, else number of bytes received -int UDPSocket::receiveFrom(char* data, int length, char** host, int* port, int timeout) -{ - if( m_sock < 0 ) - { - return -1; - } - - struct sockaddr_in remoteHost; - - //Populate m_remoteHost - std::memset(&remoteHost, 0, sizeof(struct sockaddr_in)); - - socklen_t remoteHostLen = sizeof(remoteHost); - - size_t readLen = 0; - struct timeval t_val; //t_val will be decremented on each call to select() - t_val.tv_sec = timeout / 1000; - t_val.tv_usec = (timeout - (t_val.tv_sec * 1000)) * 1000; - - //No loop here as we don't want to mix packets from different sources - do - { - //Wait for socket to be readable - //Creating FS set - fd_set socksSet; - FD_ZERO(&socksSet); - FD_SET(m_sock, &socksSet); - int ret = ::select(FD_SETSIZE, &socksSet, NULL, NULL, &t_val); - if(ret <= 0 || !FD_ISSET(m_sock, &socksSet)) - { - break; //Timeout -- FIXME should we return -1 or writtenLength ? - } +int UDPSocket::receiveFrom(char* data, int length, char** host, int* port, int timeout) { + if (_sock_fd < 0) + return -1; + + set_timeout(timeout); + if (wait_readable() != 0) + return -1; + + struct sockaddr_in remoteHost; + std::memset(&remoteHost, 0, sizeof(struct sockaddr_in)); - ret = ::recvfrom(m_sock, data + readLen, length - readLen, 0, (struct sockaddr*)&remoteHost, &remoteHostLen); - if( ret > 0) - { - readLen += ret; - } - else if( ret == 0 ) - { - //Connection was closed by server -- FIXME how do we signal that the connection was closed ? - //Continue and populate address - } - else - { - return -1; //Connection error - } - } while(0); - - static char hostBuf[16]; - inet_ntoa_r(remoteHost.sin_addr, hostBuf, sizeof(hostBuf)); - - *host = hostBuf; - *port = ntohs(remoteHost.sin_port); - - return readLen; + socklen_t remoteHostLen = sizeof(remoteHost); + int n = lwip_recvfrom(_sock_fd, data, length, 0, (struct sockaddr*) &remoteHost, &remoteHostLen); + if (n < 0) + return -1; + + static char hostBuf[16]; + inet_ntoa_r(remoteHost.sin_addr, hostBuf, sizeof(hostBuf)); + + *host = hostBuf; + *port = ntohs(remoteHost.sin_port); + + return n; } -int UDPSocket::close() -{ - if( m_sock < 0 ) - { - return -1; - } - - ::close(m_sock); - m_sock = -1; - - return 0; +UDPSocket::~UDPSocket() { + close(); //Don't want to leak } - -int UDPSocket::init() -{ - if( m_sock != -1 ) - { - return -1; - } - m_sock = ::socket(AF_INET, SOCK_DGRAM, 0); //UDP socket - if (m_sock < 0) - { - return -1; //Could not create socket (Out of memory / available descriptors) - } - return 0; -}