PlainDatagramSocketImplpublic class PlainDatagramSocketImpl extends DatagramSocketImpl The default, concrete instance of datagram sockets. This class does not
support security checks. Alternative types of DatagramSocketImpl's may be
used by setting the impl.prefix system property. |
Fields Summary |
---|
static final int | MULTICAST_IF | static final int | MULTICAST_TTL | static final int | TCP_NODELAY | static final int | FLAG_SHUTDOWN | private static final int | SO_BROADCAST | static final int | IP_MULTICAST_ADD | static final int | IP_MULTICAST_DROP | static final int | IP_MULTICAST_TTL | static final int | REUSEADDR_AND_REUSEPORTfor datagram and multicast sockets we have to set REUSEADDR and REUSEPORT
when REUSEADDR is set for other types of sockets we need to just set
REUSEADDR therefore we have this other option which sets both if
supported by the platform. this cannot be in SOCKET_OPTIONS because since
it is a public interface it ends up being public even if it is not
declared public | private boolean | bindToDevice | private byte[] | ipaddress | private int | ttl | private org.apache.harmony.luni.platform.INetworkSystem | netImpl | private volatile boolean | isNativeConnected | public int | receiveTimeout | public boolean | streaming | public boolean | shutdownInput | private InetAddress | connectedAddressused to keep address to which the socket was connected to at the native
level | private int | connectedPort | private int | trafficClassused to store the trafficClass value which is simply returned as the
value that was set. We also need it to pass it to methods that specify an
address packets are going to be sent to |
Constructors Summary |
---|
public PlainDatagramSocketImpl(FileDescriptor fd, int localPort)
super();
this.fd = fd;
this.localPort = localPort;
| public PlainDatagramSocketImpl()
super();
fd = new FileDescriptor();
|
Methods Summary |
---|
public void | bind(int port, java.net.InetAddress addr)
String prop = AccessController.doPrivileged(new PriviAction<String>("bindToDevice")); //$NON-NLS-1$
boolean useBindToDevice = prop != null && prop.toLowerCase().equals("true"); //$NON-NLS-1$
bindToDevice = netImpl.bind2(fd, port, useBindToDevice, addr);
if (0 != port) {
localPort = port;
} else {
localPort = netImpl.getSocketLocalPort(fd, NetUtil.preferIPv6Addresses());
}
try {
// Ignore failures
setOption(SO_BROADCAST, Boolean.TRUE);
} catch (IOException e) {
}
| public void | close()
synchronized (fd) {
if (fd.valid()) {
try {
netImpl.socketClose(fd);
} catch (IOException e) {
}
fd = new FileDescriptor();
}
}
| public void | connect(java.net.InetAddress inetAddr, int port)
// connectDatagram impl2
netImpl.connectDatagram(fd, port, trafficClass, inetAddr);
// if we get here then we are connected at the native level
try {
connectedAddress = InetAddress.getByAddress(inetAddr.getAddress());
} catch (UnknownHostException e) {
// this is never expected to happen as we should not have gotten
// here if the address is not resolvable
throw new SocketException(Msg.getString("K0317", inetAddr.getHostName())); //$NON-NLS-1$
}
connectedPort = port;
isNativeConnected = true;
| public void | create()
netImpl.createDatagramSocket(fd, NetUtil.preferIPv4Stack());
| public void | disconnect()
try {
netImpl.disconnectDatagram(fd);
} catch (Exception e) {
// there is currently no way to return an error so just eat any
// exception
}
connectedPort = -1;
connectedAddress = null;
isNativeConnected = false;
| protected void | finalize()
close();
| public java.lang.Object | getOption(int optID)
if (optID == SocketOptions.SO_TIMEOUT) {
return Integer.valueOf(receiveTimeout);
} else if (optID == SocketOptions.IP_TOS) {
return Integer.valueOf(trafficClass);
} else {
// Call the native first so there will be
// an exception if the socket if closed.
Object result = netImpl.getSocketOption(fd, optID);
if (optID == SocketOptions.IP_MULTICAST_IF
&& (netImpl.getSocketFlags() & MULTICAST_IF) != 0) {
try {
return InetAddress.getByAddress(ipaddress);
} catch (UnknownHostException e) {
return null;
}
}
return result;
}
| public byte | getTTL()
// Call the native first so there will be an exception if the socket if
// closed.
byte result = ((Byte) getOption(IP_MULTICAST_TTL)).byteValue();
if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
return (byte) ttl;
}
return result;
| public int | getTimeToLive()
// Call the native first so there will be an exception if the socket if
// closed.
int result = (((Byte) getOption(IP_MULTICAST_TTL)).byteValue()) & 0xFF;
if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
return ttl;
}
return result;
| public void | join(java.net.InetAddress addr)
setOption(IP_MULTICAST_ADD, new GenericIPMreq(addr));
| public void | joinGroup(java.net.SocketAddress addr, java.net.NetworkInterface netInterface)
if (addr instanceof InetSocketAddress) {
InetAddress groupAddr = ((InetSocketAddress) addr).getAddress();
setOption(IP_MULTICAST_ADD, new GenericIPMreq(groupAddr, netInterface));
}
| public void | leave(java.net.InetAddress addr)
setOption(IP_MULTICAST_DROP, new GenericIPMreq(addr));
| public void | leaveGroup(java.net.SocketAddress addr, java.net.NetworkInterface netInterface)
if (addr instanceof InetSocketAddress) {
InetAddress groupAddr = ((InetSocketAddress) addr).getAddress();
setOption(IP_MULTICAST_DROP, new GenericIPMreq(groupAddr, netInterface));
}
| protected int | peek(java.net.InetAddress sender)
if (isNativeConnected) {
/*
* in this case we know the port and address from which the data
* must have be been received as the socket is connected. However,
* we still need to do the receive in order to know that there was
* data received. We use a short buffer as we don't actually need
* the packet, only the knowledge that it is there
*/
byte[] storageArray = new byte[10];
DatagramPacket pack = new DatagramPacket(storageArray, storageArray.length);
netImpl.recvConnectedDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
.getLength(), receiveTimeout, true); // peek
// to set the sender ,we now use a native function
// sender.ipaddress = connectedAddress.getAddress();
netImpl.setInetAddress(sender, connectedAddress.getAddress());
return connectedPort;
}
return netImpl.peekDatagram(fd, sender, receiveTimeout);
| public int | peekData(java.net.DatagramPacket pack)
try {
if (isNativeConnected) {
netImpl.recvConnectedDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
.getLength(), receiveTimeout, true); // peek
updatePacketRecvAddress(pack);
} else {
// receiveDatagram 2
netImpl.receiveDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
.getLength(), receiveTimeout, true); // peek
}
} catch (InterruptedIOException e) {
throw new SocketTimeoutException(e.toString());
}
return pack.getPort();
| public void | receive(java.net.DatagramPacket pack)
try {
if (isNativeConnected) {
// do not peek
netImpl.recvConnectedDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
.getLength(), receiveTimeout, false);
updatePacketRecvAddress(pack);
} else {
// receiveDatagramImpl2
netImpl.receiveDatagram(fd, pack, pack.getData(), pack.getOffset(), pack
.getLength(), receiveTimeout, false);
}
} catch (InterruptedIOException e) {
throw new SocketTimeoutException(e.getMessage());
}
| public void | send(java.net.DatagramPacket packet)
if (isNativeConnected) {
netImpl.sendConnectedDatagram(fd, packet.getData(), packet.getOffset(), packet
.getLength(), bindToDevice);
} else {
// sendDatagramImpl2
netImpl.sendDatagram(fd, packet.getData(), packet.getOffset(), packet.getLength(),
packet.getPort(), bindToDevice, trafficClass, packet.getAddress());
}
| public void | setOption(int optID, java.lang.Object val)Set the nominated socket option. As the timeouts are not set as options
in the IP stack, the value is stored in an instance field.
/*
* for datagram sockets on some platforms we have to set both the
* REUSEADDR AND REUSEPORT so for REUSEADDR set this option option which
* tells the VM to set the two values as appropriate for the platform
*/
if (optID == SocketOptions.SO_REUSEADDR) {
optID = REUSEADDR_AND_REUSEPORT;
}
if (optID == SocketOptions.SO_TIMEOUT) {
receiveTimeout = ((Integer) val).intValue();
} else {
int flags = netImpl.getSocketFlags();
try {
netImpl.setSocketOption(fd, optID | (flags << 16), val);
} catch (SocketException e) {
// we don't throw an exception for IP_TOS even if the platform
// won't let us set the requested value
if (optID != SocketOptions.IP_TOS) {
throw e;
}
}
if (optID == SocketOptions.IP_MULTICAST_IF && (flags & MULTICAST_IF) != 0) {
InetAddress inet = (InetAddress) val;
if (NetUtil.bytesToInt(inet.getAddress(), 0) == 0 || inet.isLoopbackAddress()) {
ipaddress = ((InetAddress) val).getAddress();
} else {
InetAddress local = null;
try {
local = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
throw new SocketException("getLocalHost(): " + e.toString());
}
if (inet.equals(local)) {
ipaddress = ((InetAddress) val).getAddress();
} else {
throw new SocketException(val + " != getLocalHost(): " + local);
}
}
}
/*
* save this value as it is actually used differently for IPv4 and
* IPv6 so we cannot get the value using the getOption. The option
* is actually only set for IPv4 and a masked version of the value
* will be set as only a subset of the values are allowed on the
* socket. Therefore we need to retain it to return the value that
* was set. We also need the value to be passed into a number of
* natives so that it can be used properly with IPv6
*/
if (optID == SocketOptions.IP_TOS) {
trafficClass = ((Integer) val).intValue();
}
}
| public void | setTTL(byte ttl)
setOption(IP_MULTICAST_TTL, Byte.valueOf(ttl));
if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
this.ttl = ttl;
}
| public void | setTimeToLive(int ttl)
setOption(IP_MULTICAST_TTL, Byte.valueOf((byte) (ttl & 0xFF)));
if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
this.ttl = ttl;
}
| private void | updatePacketRecvAddress(java.net.DatagramPacket packet)Set the received address and port in the packet. We do this when the
Datagram socket is connected at the native level and the
recvConnnectedDatagramImpl does not update the packet with address from
which the packet was received
packet.setAddress(connectedAddress);
packet.setPort(connectedPort);
|
|