| /* |
| * 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 <log4cxx/logstring.h> |
| #include <log4cxx/helpers/datagramsocket.h> |
| #include <log4cxx/helpers/datagrampacket.h> |
| #include <log4cxx/helpers/loglog.h> |
| #include <log4cxx/helpers/transcoder.h> |
| |
| #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); |
| } |
| } |