542 lines
24 KiB
XML
542 lines
24 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
|
<chapter id="ip">
|
|
<title>TCP and UDP Support</title>
|
|
<para>
|
|
Spring Integration provides Channel Adapters for receiving and sending messages over internet protocols. Both UDP
|
|
(User Datagram Protocol)
|
|
and TCP (Transmission Control Protocol) adapters are provided. Each adapter provides for one-way communication
|
|
over the underlying protocol. Gateways providing two-way communication may be considered in a future release.
|
|
</para>
|
|
<section id="ip-intro">
|
|
<title>Introduction</title>
|
|
<para>
|
|
Two flavors each of UDP inbound and outbound adapters are provided <classname>UnicastSendingMessageHandler</classname>
|
|
sends a datagram packet to a single destination. <classname>UnicastReceivingChannelAdapter</classname> receives
|
|
incoming datagram packets. <classname>MulticastSendingMessageHandler</classname> sends (broadcasts) datagram packets to
|
|
a multicast address. <classname>MulticastReceivingChannelAdapter</classname> receives incoming datagram packets
|
|
by joining to a multicast address.
|
|
</para>
|
|
<para>
|
|
Two flavors each of TCP inbound and outbound adapters are provided <classname>TcpNetSendingMessageHandler</classname>
|
|
and <classname>TcpNioSendingMessageHandler</classname> send messages over TCP. They are functionally equivalent,
|
|
but use different underlying technology for socket communication. Similarly, <classname>TcpNetReceivingChannelAdapter</classname>
|
|
and <classname>TcpNioReceivingChannelAdapter</classname> are the equivalent inbound channel adapters.
|
|
The choice of which to use in what circumstances is described below.
|
|
</para>
|
|
</section>
|
|
<section id="udp-adapters">
|
|
<title>UDP Adapters</title>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[ <ip:outbound-channel-adapter id="udpOut"
|
|
protocol="udp"
|
|
host="somehost"
|
|
port="11111"
|
|
multicast="false"
|
|
channel="exampleChannel" />]]></programlisting>
|
|
A simple UDP outbound channel adapter.
|
|
<tip>
|
|
When setting multicast to true, provide the multicast address in the host
|
|
attribute.
|
|
</tip>
|
|
</para>
|
|
<para>
|
|
UDP is an efficient, but unreliable protocol. Two attributes are added to improve reliability. When check-length is
|
|
set to true, the adapter precedes the message data with a length field (4 bytes in network byte order). This enables
|
|
the receiving side to verify the length of the packet received. If a receiving system uses a buffer that is too
|
|
short the contain the packet, the packet can be truncated. The length header provides a mechanism to detect this.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[ <ip:outbound-channel-adapter id="udpOut"
|
|
protocol="udp"
|
|
host="somehost"
|
|
port="11111"
|
|
multicast="false"
|
|
check-length="true"
|
|
channel="exampleChannel" />]]></programlisting>
|
|
An outbound channel adapter that adds length checking to the datagram packets.
|
|
<tip>
|
|
The recipient of the packet must also be configured to expect a length to precede the
|
|
actual data. For a Spring Integration UDP inbound channel adapter, set its
|
|
<classname>check-length</classname> attribute.
|
|
</tip>
|
|
</para>
|
|
<para>
|
|
The second reliability improvement allows an application-level acknowledgment protocol to be used. The receiver
|
|
must send an acknowledgment to the sender within a specified time.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[ <ip:outbound-channel-adapter id="udpOut"
|
|
protocol="udp"
|
|
host="somehost"
|
|
port="11111"
|
|
multicast="false"
|
|
check-length="true"
|
|
acknowledge="true"
|
|
ack-host="thishost"
|
|
ack-port="22222"
|
|
ack-timeout="10000"
|
|
channel="exampleChannel" />]]></programlisting>
|
|
An outbound channel adapter that adds length checking to the datagram packets and waits for an acknowledgment.
|
|
<tip>
|
|
Setting acknowledge to true implies the recipient of the packet can interpret the header added to the packet
|
|
containing acknowledgment data (host and port). Most likely, the recipient will be a Spring Integration inbound
|
|
channel adapter.
|
|
</tip>
|
|
<tip>
|
|
When multicast is true, an additional attribute min-acks-for-success specifies
|
|
how many acknowledgments must be received within the ack-timeout.
|
|
</tip>
|
|
</para>
|
|
<para>
|
|
For even more reliable networking, TCP can be used.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[ <ip:inbound-channel-adapter id="udpReceiver"
|
|
channel="udpOutChannel"
|
|
protocol="udp"
|
|
port="11111"
|
|
receive-buffer-size="500"
|
|
multicast="false"
|
|
check-length="true" />]]></programlisting>
|
|
A basic unicast inbound udp channel adapter.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[ <ip:inbound-channel-adapter id="udpReceiver"
|
|
channel="udpOutChannel"
|
|
protocol="udp"
|
|
port="11111"
|
|
receive-buffer-size="500"
|
|
multicast="true"
|
|
multicast-address="225.6.7.8"
|
|
check-length="true" />]]></programlisting>
|
|
A basic multicast inbound udp channel adapter.
|
|
</para>
|
|
</section>
|
|
<section id="tcp-adapters">
|
|
<title>TCP Adapters</title>
|
|
<para>
|
|
Two versions of TCP inbound and outbound channel adapters are provided; these adapters
|
|
use either java.net.Socket IO, or java.nio.channels.SocketChannel IO. The choice of which
|
|
to use depends on the application. The TcpNet* adapters use java.net.Socket and the TcpNio*
|
|
adapters use java.nio.channels.ChannelSocket. It is not anticipated that much difference in
|
|
performance, if any, would exist between these technologies on the outbound side. This is
|
|
because each outbound adapter sends data over only one socket. On the receiving side
|
|
however, consideration should be given to the number of connections. For the
|
|
<classname>TcpNetReceivingChannelAdapter</classname> a thread is dedicated to receiving
|
|
data on each connected socket; the pool size must therefore be set large enough to handle
|
|
the expected number of connections. For the <classname>TcpNioReceivingChannelAdapter</classname>
|
|
threads are used on an as-needed basis and it is likely that many fewer threads would be
|
|
needed. If a small number of connections is expected, we expect that the the TcpNetReceivingChannelAdapter
|
|
will give the best performance. For large number of connections, the TcpNioReceivingChannelAdapter will
|
|
likely give the best performance. In addition, the TcpNioReceivingChannelAdapter provides an
|
|
attribute <classname>using-direct-buffers</classname> which attempts to use direct buffers. See
|
|
<classname>java.nio.ByteBuffer</classname> for more information about direct buffers.
|
|
<tip>
|
|
It is not expected that direct buffers will offer much, if any, performance difference. You
|
|
should experiment with the use of TcpNxx* adapters, and direct buffers when using TcpNio*
|
|
adapters to determine the best performance in your environment.
|
|
</tip>
|
|
</para>
|
|
<para>
|
|
TCP is a streaming protocol; this means that some structure has to be provided to data
|
|
transported over TCP, so the receiver can demarcate the data into discrete messages.
|
|
Three standard message formats are provided for this purpose; you can also provide code
|
|
for your own custom format. The first of the three standard formats is length-header, in which case a 4 byte
|
|
length header precedes the data; this is the default. The second is stx-etx in which the message
|
|
data is preceded by an STX (0x02) character and terminated with an ETX (0x03) character.
|
|
The third is crlf in which the message is terminated with a carriage return and line feed
|
|
(\r\n). The first format (the default) is likely to be the most performant. This is because
|
|
we can determine exactly how many bytes to read to obtain the complete message. The other
|
|
two formats require examining each byte to determine if the end of the message has been
|
|
received. This length-header format can also handle binary data. The other two formats an only handle
|
|
text data (specifcally, data that does not contain characters 0x02 and 0x03 for stx-etx and
|
|
0x0d and 0x0a for crlf. This limitation can be avoided by appropriate character escaping techniques
|
|
in the application layer. No such escaping is provided by the adapters.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[ <ip:outbound-channel-adapter id="tcpOut"
|
|
channel="inChannel"
|
|
protocol="tcp"
|
|
host="somehost"
|
|
port="11111"
|
|
message-format="length-header"
|
|
using-nio="true"
|
|
using-direct-buffers="false"
|
|
so-keep-alive="true"
|
|
so-timeout="10000"
|
|
/>]]></programlisting>
|
|
A basic outbound tcp channel adapter. This adapter uses java.nio.channels.SocketChannel.
|
|
To use a java.net.Socket, set <classname>using-nio</classname> to false and
|
|
<classname>using-direct-buffers</classname> is not relevant.
|
|
</para>
|
|
<para>
|
|
<programlisting language="xml"><![CDATA[ <ip:inbound-channel-adapter id="tcp1"
|
|
channel="channel"
|
|
protocol="tcp"
|
|
port="11111"
|
|
message-format="length-header"
|
|
using-nio="true"
|
|
using-direct-buffers="false"
|
|
pool-size="2"
|
|
so-keep-alive="true"
|
|
so-timeout="10000"
|
|
/>]]></programlisting>
|
|
A basic inbound tcp channel adapter. This adapter uses java.nio.channels.SocketChannel.
|
|
To use a java.net.Socket, set <classname>using-nio</classname> to false and
|
|
<classname>using-direct-buffers</classname> is not relevant.
|
|
</para>
|
|
</section>
|
|
<section id="ip-adapter-reference">
|
|
<title>IP Adapter Attributes</title>
|
|
<para>
|
|
<table id="ip-ob-adapter-attributes">
|
|
<title>IP Outbound Channel Adapter Attributes</title>
|
|
<tgroup cols="5">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="0.3*" align="center"/>
|
|
<colspec colnum="3" colname="col3" colwidth="0.3*" align="center"/>
|
|
<colspec colnum="4" colname="col4" colwidth="1*"/>
|
|
<colspec colnum="5" colname="col5" colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Attribute Name</entry>
|
|
<entry align="center">TCP?</entry>
|
|
<entry align="center">UDP?</entry>
|
|
<entry align="center">Allowed Values</entry>
|
|
<entry align="center">Attribute Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>protocol</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>tcp, udp</entry>
|
|
<entry>Determines whether the adapter uses TCP or UDP, over IP.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>host</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>The host name or ip address of the destination. For multicast udp
|
|
adapters, the multicast address.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>port</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>The port on the destination.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>multicast</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not the udp adapter uses multicast.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>acknowledge</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not a udp adapter requires an acknowledgment from the destination.
|
|
when enabled, requires setting the following 4 attributes.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ack-host</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>When acknowledge is true, indicates the host or ip address to which the
|
|
acknowledgment should be sent. Usually the current host, but may be
|
|
different, for example when Network Address Transation (NAT) is
|
|
being used.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ack-port</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>When acknowledge is true, indicates the port to which the
|
|
acknowledgment should be sent. The adapter listens on this port for
|
|
acknowledgments.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>ack-timeout</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>When acknowledge is true, indicates the time in milliseconds that the
|
|
adapter will wait for an acknowlegment. If an acknowlegment is not
|
|
received in time, the adapter will throw an exception.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>min-acks-for- success</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>Defaults to 1. For multicast adapters, you can set this to a larger
|
|
value, requiring acknowlegments from multiple destinations.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>check-length</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not a udp adapter includes a data length field in the
|
|
packet sent to the destination.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>time-to-live</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>For multicast adapters, specifies the time to live attribute for
|
|
the <classname>MulticastSocket</classname>; controls the scope
|
|
of the multicasts. Refer to the Java API
|
|
documentation for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>using-nio</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not the tcp adapter is using NIO. Refer to the java.nio
|
|
package for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>using-direct-buffers</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>true, false</entry>
|
|
<entry>When using NIO, whether or not the tcp adapter uses direct buffers.
|
|
Refer to <classname>java.nio.ByteBuffer</classname> documentation for
|
|
more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>message-format</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>length-header, stx-etx, crlf, custom</entry>
|
|
<entry>The formatting that the tcp adapter uses so the receiver can demarcate
|
|
messages. Defaults to length-header.
|
|
See the discussion above for details about each format.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>custom-socket- writer-class-name</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>Subclass of TcpNetSocket- Writer or TcpNioSocket- Writer</entry>
|
|
<entry>When message-format is 'custom' the name of the class that
|
|
implements the custom format. Must be a subclass of the TcpNxxSocketWriter,
|
|
depending on whether using-nio is false or true.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-timeout</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.Socket</classname> and <classname>java.net.DatagramSocket</classname>
|
|
setSoTimeout() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-send-buffer-size</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.Socket</classname> and <classname>java.net.DatagramSocket</classname>
|
|
setSendBufferSize() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-receive-buffer- size</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>Used for udp acknowlegment packets. See <classname>java.net.DatagramSocket</classname>
|
|
setReceiveBufferSize() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-keep-alive</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>true, false</entry>
|
|
<entry>See <classname>java.net.Socket. setKeepAlive()</classname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-linger</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry></entry>
|
|
<entry>Sets linger to true with supplied value.
|
|
See <classname>java.net.Socket. setSoLinger()</classname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-tcp-no-delay</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>true, false</entry>
|
|
<entry>See <classname>java.net.Socket. setTcpNoDelay()</classname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-traffic-class</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.Socket. setTrafficClass()</classname>.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<table id="ip-ib-adapter-attributes">
|
|
<title>IP Inbound Channel Adapter Attributes</title>
|
|
<tgroup cols="5">
|
|
<colspec align="left" />
|
|
<colspec colnum="1" colname="col1" colwidth="1*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="0.3*" align="center"/>
|
|
<colspec colnum="3" colname="col3" colwidth="0.3*" align="center"/>
|
|
<colspec colnum="4" colname="col4" colwidth="1*"/>
|
|
<colspec colnum="5" colname="col5" colwidth="2*"/>
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Attribute Name</entry>
|
|
<entry align="center">TCP?</entry>
|
|
<entry align="center">UDP?</entry>
|
|
<entry align="center">Allowed Values</entry>
|
|
<entry align="center">Attribute Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>protocol</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry>tcp, udp</entry>
|
|
<entry>Determines whether the adapter uses TCP or UDP, over IP.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>port</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>The port on which the adapter listens.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>multicast</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not the udp adapter uses multicast.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>multicast-address</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>When multicast is true, the multicast address to which the adapter
|
|
joins.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>pool-size</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>Specifies the concurrency. For udp, specifies how many packets can
|
|
be handled concurrently. For tcp, not using nio, specifies the
|
|
number of concurrent connections supported by the adapter. For tcp,
|
|
using nio, specifies the number of tcp fragments that are concurrently
|
|
reassembled into complete messages.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>receive-buffer-size</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>For udp, the size of the buffer used to receive DatagramPackets.
|
|
Usually set to the MTU size. If a smaller buffer is used than the
|
|
size of the sent packet, truncation can occur. This can be detected
|
|
by means of the check-length attribute.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>check-length</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not a udp adapter expects a data length field in the
|
|
packet received. Used to detect packet truncation.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>using-nio</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>true, false</entry>
|
|
<entry>Whether or not the tcp adapter is using NIO. Refer to the java.nio
|
|
package for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>using-direct-buffers</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>true, false</entry>
|
|
<entry>When using NIO, whether or not the tcp adapter uses direct buffers.
|
|
Refer to java.nio.ByteBuffer documentation for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>message-format</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>length-header, stx-etx, crlf, custom</entry>
|
|
<entry>The formatting that the tcp adapter uses so the adapter can demarcate
|
|
messages. Defaults to length-header.
|
|
See the discussion above for details about each format.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>custom-socket- reader-class-name</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>Subclass of TcpNetSocket- Reader or TcpNioSocket- Reader</entry>
|
|
<entry>When message-format is 'custom' the name of the class that
|
|
implements the custom format. Must be a subclass of the TcpNxxSocketReader,
|
|
depending on whether using-nio is false or true.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-timeout</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.Socket</classname> and <classname>java.net.DatagramSocket</classname>
|
|
setSoTimeout() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-send-buffer-size</entry>
|
|
<entry>N</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>Used for udp acknowlegment packets. See <classname>java.net.DatagramSocket</classname>
|
|
setSendBufferSize() methods for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-receive-buffer- size</entry>
|
|
<entry>Y</entry>
|
|
<entry>Y</entry>
|
|
<entry></entry>
|
|
<entry>See <classname>java.net.Socket</classname> and <classname>java.net.DatagramSocket</classname>
|
|
setReceiveBufferSize() for more information.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>so-keep-alive</entry>
|
|
<entry>Y</entry>
|
|
<entry>N</entry>
|
|
<entry>true, false</entry>
|
|
<entry>See <classname>java.net.Socket. setKeepAlive()</classname>.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
</para>
|
|
</section>
|
|
</chapter>
|