[编织消息框架][传输协议]sctp简单开发

jdk1.7支持sctp协议,需要linux安装sctp支持库

测试代码

 1 public class ServerSCTP {
 2     static int SERVER_PORT = 3456;
 3     static int US_STREAM = 0;
 4     static int FR_STREAM = 1;
 5 
 6     static SimpleDateFormat USformatter = new SimpleDateFormat("h:mm:ss a EEE d MMM yy, zzzz", Locale.US);
 7     static SimpleDateFormat FRformatter = new SimpleDateFormat("h:mm:ss a EEE d MMM yy, zzzz", Locale.FRENCH);
 8 
 9     @SuppressWarnings("restriction")
10     public static void main(String[] args) throws IOException {
11         com.sun.nio.sctp.SctpServerChannel ssc = com.sun.nio.sctp.SctpServerChannel.open();
12         ssc.bind(new InetSocketAddress(SERVER_PORT));
13 
14         ByteBuffer buf = ByteBuffer.allocateDirect(60);
15         CharBuffer cbuf = CharBuffer.allocate(60);
16         CharsetEncoder encoder = Charset.forName("ISO-8859-1").newEncoder();
17 
18         while (true) {
19             com.sun.nio.sctp.SctpChannel sc = ssc.accept();
20 
21             /* get the current date */
22             Date today = new Date();
23             cbuf.put(USformatter.format(today)).flip();
24             encoder.encode(cbuf, buf, true);
25             buf.flip();
26 
27             /* send the message on the US stream */
28             com.sun.nio.sctp.MessageInfo messageInfo = com.sun.nio.sctp.MessageInfo.createOutgoing(null, US_STREAM);
29             sc.send(buf, messageInfo);
30 
31             /* update the buffer with French format */
32             cbuf.clear();
33             cbuf.put(FRformatter.format(today)).flip();
34             buf.clear();
35             encoder.encode(cbuf, buf, true);
36             buf.flip();
37 
38             /* send the message on the French stream */
39             messageInfo.streamNumber(FR_STREAM);
40             sc.send(buf, messageInfo);
41 
42             cbuf.clear();
43             buf.clear();
44 
45             sc.close();
46         }
47     }
48 }
 1 @SuppressWarnings("restriction")
 2 public class ClientSCTP {
 3     static int SERVER_PORT = 3456;
 4     public void run() throws IOException {
 5         ByteBuffer buf = ByteBuffer.allocateDirect(60);
 6         Charset charset = Charset.forName("ISO-8859-1");
 7         CharsetDecoder decoder = charset.newDecoder();
 8 
 9         com.sun.nio.sctp.SctpChannel sc = com.sun.nio.sctp.SctpChannel.open(new InetSocketAddress("localhost", SERVER_PORT), 0, 0);
10 
11         /* handler to keep track of association setup and termination */
12         AssociationHandler assocHandler = new AssociationHandler();
13         /* expect two messages and two notifications */
14         com.sun.nio.sctp.MessageInfo messageInfo = null;
15         do {
16             messageInfo = sc.receive(buf, System.out, assocHandler);
17             buf.flip();
18 
19             if (buf.remaining() > 0 && messageInfo.streamNumber() == ServerSCTP.US_STREAM) {
20 
21             System.out.println("(US) " + decoder.decode(buf).toString());
22             } else if (buf.remaining() > 0 && messageInfo.streamNumber() == ServerSCTP.FR_STREAM) {
23             System.out.println("(FR) " + decoder.decode(buf).toString());
24             }
25             buf.clear();
26         } while (messageInfo != null);
27 
28         sc.close();
29     }
30 
31     public static void main(String[] args) throws IOException {
32         new ClientSCTP().run();
33     }
34 
35     static class AssociationHandler extends com.sun.nio.sctp.AbstractNotificationHandler<PrintStream> {
36         public com.sun.nio.sctp.HandlerResult handleNotification(com.sun.nio.sctp.AssociationChangeNotification not, PrintStream stream) {
37             if (not.event().equals(com.sun.nio.sctp.AssociationChangeNotification.AssocChangeEvent.COMM_UP)) {
38                 int outbound = not.association().maxOutboundStreams();
39                 int inbound = not.association().maxInboundStreams();
40                 stream.printf("New association setup with %d outbound streams" + ", and %d inbound streams.\n", outbound, inbound);
41             }
42 
43             return com.sun.nio.sctp.HandlerResult.CONTINUE;
44         }
45 
46         public com.sun.nio.sctp.HandlerResult handleNotification(com.sun.nio.sctp.ShutdownNotification not, PrintStream stream) {
47             stream.printf("The association has been shutdown.\n");
48             return com.sun.nio.sctp.HandlerResult.RETURN;
49         }
50     }
51 }

导出ClientSCTP.class,ServerSCTP.class

环境部署

1.linux检查是否支持sctp,官方提示必须内核2.6版本以上,有信息显示代表已安装

lsmod | grep sctp

1.1如果没有就下载

官方:http://lksctp.sourceforge.net/

github:https://github.com/sctp/lksctp-tools

tar -zxf lksctp-tools-1.0.17.tar.gz

cd lksctp-tools-1.0.17

./configure

make

make install

2.执行  ./java8.sh -jar testsctp.jar 抛异常 

java.lang.UnsupportedOperationException: libsctp.so.1: cannot open shared object file: No such file or directory

原因是没有配置 $LD_LIBRARY_PATH 环境变量

echo $LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/lib

继续执行 ./java8.sh -jar testsctp.jar 还是抛异常 

java.net.SocketException: Protocol not supported

原因是系统没有加载lksctp模块

modprobe sctp

lsmod |grep sctp

再执行出现连接异常 

java.net.SocketException: Permission denied

原因是linux selinux 安全限制,解决方式临时关闭

setenforce 0

永久关闭

ehco "SELINUX=disabled" >> /etc/selinux/config 

本人测试:连接60000client没aio快,原因是sctp建立链接要求四次握手

posted @ 2017-04-24 16:50  solq321  阅读(849)  评论(0编辑  收藏  举报