Files
spring-integration/spring-integration-reference/src/ip.xml
2010-03-11 23:12:09 +00:00

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>