/** * Creates a network access point. * * @param socket the socket that this access point is supposed to use for communication. * @param messageQueue the FIFO list where incoming messages should be queued * @param errorHandler the instance to notify when errors occur. */ protected Connector( IceSocketWrapper socket, MessageQueue messageQueue, ErrorHandler errorHandler) { this.sock = socket; this.messageQueue = messageQueue; this.errorHandler = errorHandler; Transport transport = socket.getUDPSocket() != null ? Transport.UDP : Transport.TCP; listenAddress = new TransportAddress(socket.getLocalAddress(), socket.getLocalPort(), transport); if (transport == Transport.UDP) { remoteAddress = null; } else { Socket tcpSocket = socket.getTCPSocket(); remoteAddress = new TransportAddress(tcpSocket.getInetAddress(), tcpSocket.getPort(), transport); } }
/** The listening thread's run method. */ @Override public void run() { DatagramPacket packet = null; while (this.running) { try { IceSocketWrapper localSock; synchronized (sockLock) { if (!running) return; localSock = this.sock; } /* * Make sure localSock's receiveBufferSize is taken into * account including after it gets changed. */ int receiveBufferSize = 1500; /* if(localSock.getTCPSocket() != null) { receiveBufferSize = localSock.getTCPSocket(). getReceiveBufferSize(); } else if(localSock.getUDPSocket() != null) { receiveBufferSize = localSock.getUDPSocket(). getReceiveBufferSize(); } */ if (packet == null) { packet = new DatagramPacket(new byte[receiveBufferSize], receiveBufferSize); } else { byte[] packetData = packet.getData(); if ((packetData == null) || (packetData.length < receiveBufferSize)) { packet.setData(new byte[receiveBufferSize], 0, receiveBufferSize); } else { /* * XXX Tell the packet it is large enough because the * socket will not look at the length of the data array * property and will just respect the length property. */ packet.setLength(receiveBufferSize); } } localSock.receive(packet); // get lost if we are no longer running. if (!running) return; logger.finest("received datagram"); RawMessage rawMessage = new RawMessage( packet.getData(), packet.getLength(), new TransportAddress( packet.getAddress(), packet.getPort(), listenAddress.getTransport()), listenAddress); messageQueue.add(rawMessage); } catch (SocketException ex) { if (running) { logger.log( Level.WARNING, "Connector died: " + listenAddress + " -> " + remoteAddress, ex); stop(); // Something wrong has happened errorHandler.handleFatalError( this, "A socket exception was thrown" + " while trying to receive a message.", ex); } else { // The exception was most probably caused by calling // this.stop(). } } catch (ClosedChannelException cce) { logger.log(Level.WARNING, "A net access point has gone useless:", cce); stop(); errorHandler.handleFatalError( this, "ClosedChannelException occurred while listening" + " for messages!", cce); } catch (IOException ex) { logger.log(Level.WARNING, "A net access point has gone useless:", ex); errorHandler.handleError(ex.getMessage(), ex); // do not stop the thread; } catch (Throwable ex) { logger.log(Level.WARNING, "A net access point has gone useless:", ex); stop(); errorHandler.handleFatalError( this, "Unknown error occurred while listening for messages!", ex); } } }
/** * Sends message through this access point's socket. * * @param message the bytes to send. * @param address message destination. * @throws IOException if an exception occurs while sending the message. */ void sendMessage(byte[] message, TransportAddress address) throws IOException { DatagramPacket datagramPacket = new DatagramPacket(message, 0, message.length, address); sock.send(datagramPacket); }