/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include "apr_network_io.h" #include "apr_lib.h" using namespace log4cxx::helpers; IMPLEMENT_LOG4CXX_OBJECT(DatagramSocket) DatagramSocket::DatagramSocket() : socket(0), address(), localAddress(), port(0), localPort(0) { create(); } DatagramSocket::DatagramSocket(int localPort1) : socket(0), address(), localAddress(), port(0), localPort(0) { InetAddressPtr bindAddr = InetAddress::anyAddress(); create(); bind(localPort1, bindAddr); } DatagramSocket::DatagramSocket(int localPort1, InetAddressPtr localAddress1) : socket(0), address(), localAddress(), port(0), localPort(0) { create(); bind(localPort1, localAddress1); } DatagramSocket::~DatagramSocket() { try { close(); } catch(SocketException&) { } } /** Binds a datagram socket to a local port and address.*/ void DatagramSocket::bind(int localPort1, InetAddressPtr localAddress1) { Pool addrPool; // Create server socket address (including port number) LOG4CXX_ENCODE_CHAR(hostAddr, localAddress1->getHostAddress()); apr_sockaddr_t *server_addr; apr_status_t status = apr_sockaddr_info_get(&server_addr, hostAddr.c_str(), APR_INET, localPort1, 0, addrPool.getAPRPool()); if (status != APR_SUCCESS) { throw BindException(status); } // bind the socket to the address status = apr_socket_bind(socket, server_addr); if (status != APR_SUCCESS) { throw BindException(status); } this->localPort = localPort1; this->localAddress = localAddress1; } /** Close the socket.*/ void DatagramSocket::close() { if (socket != 0) { apr_status_t status = apr_socket_close(socket); if (status != APR_SUCCESS) { throw SocketException(status); } socket = 0; localPort = 0; } } void DatagramSocket::connect(InetAddressPtr address1, int port1) { this->address = address1; this->port = port1; Pool addrPool; // create socket address LOG4CXX_ENCODE_CHAR(hostAddr, address1->getHostAddress()); apr_sockaddr_t *client_addr; apr_status_t status = apr_sockaddr_info_get(&client_addr, hostAddr.c_str(), APR_INET, port, 0, addrPool.getAPRPool()); if (status != APR_SUCCESS) { throw ConnectException(status); } // connect the socket status = apr_socket_connect(socket, client_addr); if (status != APR_SUCCESS) { throw ConnectException(status); } } /** Creates a datagram socket.*/ void DatagramSocket::create() { apr_socket_t* newSocket; apr_status_t status = apr_socket_create(&newSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, socketPool.getAPRPool()); socket = newSocket; if (status != APR_SUCCESS) { throw SocketException(status); } } /** Receive the datagram packet.*/ void DatagramSocket::receive(DatagramPacketPtr& p) { Pool addrPool; // Create the address from which to receive the datagram packet LOG4CXX_ENCODE_CHAR(hostAddr, p->getAddress()->getHostAddress()); apr_sockaddr_t *addr; apr_status_t status = apr_sockaddr_info_get(&addr, hostAddr.c_str(), APR_INET, p->getPort(), 0, addrPool.getAPRPool()); if (status != APR_SUCCESS) { throw SocketException(status); } // receive the datagram packet apr_size_t len = p->getLength(); status = apr_socket_recvfrom(addr, socket, 0, (char *)p->getData(), &len); if (status != APR_SUCCESS) { throw IOException(status); } } /** Sends a datagram packet.*/ void DatagramSocket::send(DatagramPacketPtr& p) { Pool addrPool; // create the adress to which to send the datagram packet LOG4CXX_ENCODE_CHAR(hostAddr, p->getAddress()->getHostAddress()); apr_sockaddr_t *addr; apr_status_t status = apr_sockaddr_info_get(&addr, hostAddr.c_str(), APR_INET, p->getPort(), 0, addrPool.getAPRPool()); if (status != APR_SUCCESS) { throw SocketException(status); } // send the datagram packet apr_size_t len = p->getLength(); status = apr_socket_sendto(socket, addr, 0, (char *)p->getData(), &len); if (status != APR_SUCCESS) { throw IOException(status); } }