Subversion Repositories Programming Utils

Rev

Rev 113 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
113 rm5248 1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
#include <log4cxx/logstring.h>
18
#include <log4cxx/helpers/datagramsocket.h>
19
#include <log4cxx/helpers/datagrampacket.h>
20
#include <log4cxx/helpers/loglog.h>
21
#include <log4cxx/helpers/transcoder.h>
22
 
115 rm5248 23
#ifndef LOG4CXX_QT
113 rm5248 24
#include "apr_network_io.h"
25
#include "apr_lib.h"
115 rm5248 26
#else
27
#include <QHostAddress>
28
#include <QByteArray>
29
#endif
113 rm5248 30
 
31
using namespace log4cxx::helpers;
32
 
33
IMPLEMENT_LOG4CXX_OBJECT(DatagramSocket)
34
 
35
DatagramSocket::DatagramSocket()
36
 : socket(0), address(), localAddress(), port(0), localPort(0)
37
{
38
   create();
39
}
40
 
41
DatagramSocket::DatagramSocket(int localPort1)
42
 : socket(0), address(), localAddress(), port(0), localPort(0)
43
{
44
   InetAddressPtr bindAddr = InetAddress::anyAddress();
45
 
46
   create();
47
   bind(localPort1, bindAddr);
48
}
49
 
50
DatagramSocket::DatagramSocket(int localPort1, InetAddressPtr localAddress1)
51
 : socket(0), address(), localAddress(), port(0), localPort(0)
52
{
53
   create();
54
   bind(localPort1, localAddress1);
55
}
56
 
57
DatagramSocket::~DatagramSocket()
58
{
59
   try
60
   {
61
      close();
62
   }
63
   catch(SocketException&)
64
   {
65
   }
66
}
67
 
68
/**  Binds a datagram socket to a local port and address.*/
69
void DatagramSocket::bind(int localPort1, InetAddressPtr localAddress1)
70
{
71
   Pool addrPool;
72
 
73
   // Create server socket address (including port number)
74
   LOG4CXX_ENCODE_CHAR(hostAddr, localAddress1->getHostAddress());
115 rm5248 75
#ifndef LOG4CXX_QT
113 rm5248 76
   apr_sockaddr_t *server_addr;
77
   apr_status_t status =
78
       apr_sockaddr_info_get(&server_addr, hostAddr.c_str(), APR_INET,
79
                             localPort1, 0, addrPool.getAPRPool());
80
   if (status != APR_SUCCESS) {
81
     throw BindException(status);
82
   }
83
 
84
   // bind the socket to the address
85
   status = apr_socket_bind(socket, server_addr);
86
   if (status != APR_SUCCESS) {
87
     throw BindException(status);
88
   }
115 rm5248 89
#else
90
   QHostAddress localHost( localAddress1->getHostAddress().c_str() );
91
   bool status = socket->bind( localHost, localPort1 );
92
   if( !status ){
93
       throw BindException( status );
94
   }
95
#endif
113 rm5248 96
 
97
   this->localPort = localPort1;
98
   this->localAddress = localAddress1;
99
}
100
 
101
/** Close the socket.*/
102
void DatagramSocket::close()
103
{
115 rm5248 104
#ifndef LOG4CXX_QT
113 rm5248 105
   if (socket != 0) {
106
      apr_status_t status = apr_socket_close(socket);
107
      if (status != APR_SUCCESS) {
108
        throw SocketException(status);
109
      }
110
 
111
      socket = 0;
112
      localPort = 0;
113
   }
115 rm5248 114
#else
115
    if( socket->isOpen() ){
116
        socket->close();
117
    }
118
#endif
113 rm5248 119
}
120
 
121
void DatagramSocket::connect(InetAddressPtr address1, int port1)
122
{
123
 
124
   this->address = address1;
125
   this->port = port1;
126
 
127
   Pool addrPool;
128
 
129
   // create socket address
130
   LOG4CXX_ENCODE_CHAR(hostAddr, address1->getHostAddress());
115 rm5248 131
#ifndef LOG4CXX_QT
113 rm5248 132
   apr_sockaddr_t *client_addr;
133
   apr_status_t status =
134
       apr_sockaddr_info_get(&client_addr, hostAddr.c_str(), APR_INET,
135
                             port, 0, addrPool.getAPRPool());
136
   if (status != APR_SUCCESS) {
137
     throw ConnectException(status);
138
   }
139
 
140
   // connect the socket
141
   status = apr_socket_connect(socket, client_addr);
142
   if (status != APR_SUCCESS) {
143
     throw ConnectException(status);
144
   }
115 rm5248 145
#else
146
    socket->connectToHost( address1->getHostAddress().c_str(), port1 );
147
#endif
113 rm5248 148
}
149
 
150
/** Creates a datagram socket.*/
151
void DatagramSocket::create()
152
{
115 rm5248 153
#ifndef LOG4CXX_QT
113 rm5248 154
  apr_socket_t* newSocket;
155
  apr_status_t status =
156
    apr_socket_create(&newSocket, APR_INET, SOCK_DGRAM,
157
                      APR_PROTO_UDP, socketPool.getAPRPool());
158
  socket = newSocket;
159
  if (status != APR_SUCCESS) {
160
    throw SocketException(status);
161
  }
115 rm5248 162
#else
163
    socket = new QUdpSocket();
164
#endif
113 rm5248 165
}
166
 
167
/** Receive the datagram packet.*/
168
void DatagramSocket::receive(DatagramPacketPtr& p)
169
{
170
   Pool addrPool;
171
 
172
   // Create the address from which to receive the datagram packet
173
   LOG4CXX_ENCODE_CHAR(hostAddr, p->getAddress()->getHostAddress());
115 rm5248 174
#ifndef LOG4CXX_QT
113 rm5248 175
   apr_sockaddr_t *addr;
176
   apr_status_t status =
177
       apr_sockaddr_info_get(&addr, hostAddr.c_str(), APR_INET,
178
                             p->getPort(), 0, addrPool.getAPRPool());
179
   if (status != APR_SUCCESS) {
180
     throw SocketException(status);
181
   }
182
 
183
   // receive the datagram packet
184
   apr_size_t len = p->getLength();
185
   status = apr_socket_recvfrom(addr, socket, 0,
186
                                (char *)p->getData(), &len);
187
   if (status != APR_SUCCESS) {
188
     throw IOException(status);
189
   }
115 rm5248 190
#else
191
   int length = p->getLength();
192
   int status = socket->read( (char*)p->getData(), length );
193
   if( status == -1 ){
194
       throw IOException( status );
195
   }
196
#endif
113 rm5248 197
}
198
 
199
/**  Sends a datagram packet.*/
200
void DatagramSocket::send(DatagramPacketPtr& p)
201
{
202
   Pool addrPool;
203
 
204
   // create the adress to which to send the datagram packet
205
   LOG4CXX_ENCODE_CHAR(hostAddr, p->getAddress()->getHostAddress());
115 rm5248 206
#ifndef LOG4CXX_QT
113 rm5248 207
   apr_sockaddr_t *addr;
208
   apr_status_t status =
209
       apr_sockaddr_info_get(&addr, hostAddr.c_str(), APR_INET, p->getPort(),
210
                             0, addrPool.getAPRPool());
211
   if (status != APR_SUCCESS) {
212
     throw SocketException(status);
213
   }
214
 
215
   // send the datagram packet
216
   apr_size_t len = p->getLength();
217
   status = apr_socket_sendto(socket, addr, 0,
218
                              (char *)p->getData(), &len);
219
   if (status != APR_SUCCESS) {
220
     throw IOException(status);
221
   }
115 rm5248 222
#else
223
   int len = p->getLength();
224
    int status = socket->write( (const char*)p->getData(), len );
225
    if( status < 0 ){
226
        throw IOException( status );
227
    }
228
#endif
113 rm5248 229
}