|
Siena (v.1.5.5) API documentation | |||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectsiena.comm.TCPPacketReceiver
public class TCPPacketReceiver
receives packets through a TCP port. Receives packets through one-time connections to a TCP port. Accepts connections to a local port, reads one packet from the accepted socket, and closes the socket.
Field Summary | |
---|---|
static int |
AcceptPollingInterval
controls the accept-close workaround. |
static int |
DefaultPort
|
static java.lang.String |
Schema
|
Constructor Summary | |
---|---|
TCPPacketReceiver(int port_number)
create a receiver listening to the given port. |
|
TCPPacketReceiver(int port_number,
int qsize)
create a receiver listening to the given port with a given maximum queue for TCP connections. |
|
TCPPacketReceiver(java.net.ServerSocket s)
|
Method Summary | |
---|---|
byte[] |
address()
external address of this packet receiver. |
protected static java.net.InetAddress |
guessMyIPAddress()
|
protected static java.net.InetAddress |
guessMyIPAddress(java.net.DatagramSocket s)
|
protected static java.net.InetAddress |
guessMyIPAddress(java.net.ServerSocket s)
|
int |
receive(byte[] buf)
receives a packet in the given buffer. |
int |
receive(byte[] buf,
long timeout)
not yet implemented. |
void |
setHostName(java.lang.String hostname)
explicitly set the address of this packet receiver. |
void |
shutdown()
closes the receiver. |
byte[] |
uri()
Deprecated. since 1.4.0. Please use address() instead. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Methods inherited from interface siena.comm.PacketReceiver |
---|
address, uri |
Field Detail |
---|
public static final java.lang.String Schema
public static final int DefaultPort
public static int AcceptPollingInterval
java.net.ServerSocket.accept()
is broken, in the sense that there is no reliable way to
interrupt a thread blocking on accept()
, which is
necessary to make shutdown()
work properly. On some
platforms, such as JDK 1.3 on Sparc Solaris, it is possible to
interrupt accept()
by closing the server socket
(in which case accept()
raises an exception),
however that semantics is not defined in Sun's JDK (or at
least it is not documented). And in fact, other
implementations, such as Sun's JDK v.1.3 for i386 Linux, don't
behave that way.
Bottom line: we need a workaround to break out of
accept()
in a reliable way. The only workaround
I was able to figure out consists in setting a timeout on
accept()
with setSoTimeout(x)
. In
this case, accept()
either returns with an
accepted connection within x
milliseconds, or it
raises an InterruptedIOException
, in which case,
we simply exit if shutdown()
was called, or loop
otherwise.
Intuitively, lower values of
AcceptPollingInterval
make this receiver more
responsive to shutdown()
, with the disadvantage of
wasting cycles when the receiver remains active without much
incoming traffic. High values have the opposite advantages
and disadvantages.
A value of 0
means infinite timeout.
This value is appropriate for platforms that break out of
accept()
when you close the server socket. As
far as I know, these are JDK-1.3 on sparc+Solaris, win32, and
Mac OS X.
I think that in some cases you can "activate" the special
semantic of close()
on platforms that don't
normally exhibit that, by simply setting a timeout on the
server socket. This would allow us to use a very high value
for AcceptPollingInterval
. I'll leave these
esoteric methods to the extreme programmers...
If you figured out a better way to reliably break out of
java.net.ServerSocket.accept()
, and if you are
willing to share your ideas, please contact Antonio Carzaniga
<(firstname.lastname@unisi.ch)>.
Constructor Detail |
---|
public TCPPacketReceiver(int port_number) throws java.io.IOException
port_number
- must be a valid TCP port number, or it can
be 0 in which case a random port is used
if
- an I/O error occurs when opening the socket.
typically, when the given port is already in use.
java.io.IOException
public TCPPacketReceiver(int port_number, int qsize) throws java.io.IOException
port_number
- must be a valid TCP port number, or it can
be 0 in which case a random port is used
if
- an I/O error occurs when opening the socket.
typically, when the given port is already in use.
java.io.IOException
public TCPPacketReceiver(java.net.ServerSocket s) throws java.io.IOException, java.net.UnknownHostException
java.io.IOException
java.net.UnknownHostException
Method Detail |
---|
public void setHostName(java.lang.String hostname)
public void shutdown() throws PacketReceiverException
PacketReceiver
shutdown
in interface PacketReceiver
PacketReceiverException
public int receive(byte[] buf) throws PacketReceiverException
PacketReceiver
receive
in interface PacketReceiver
PacketReceiverException
- in case an error occurrs
while reading.public int receive(byte[] buf, long timeout)
receive
in interface PacketReceiver
public byte[] uri()
address()
instead.
address()
. The
reason for this change is more conceptual than practical: the
term "address" is more appropriate than the term "uri" because
it provides a way to reach a PacketReceiver
,
rather than an identifier.
public byte[] address()
:
host:
port
PacketReceiver.address()
protected static java.net.InetAddress guessMyIPAddress() throws java.net.UnknownHostException
java.net.UnknownHostException
protected static java.net.InetAddress guessMyIPAddress(java.net.ServerSocket s) throws java.net.UnknownHostException
java.net.UnknownHostException
protected static java.net.InetAddress guessMyIPAddress(java.net.DatagramSocket s) throws java.net.UnknownHostException
java.net.UnknownHostException
|
Siena (v.1.5.5) API documentation | |||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |