Mina sendmsg 多线程和单线程环境下 模拟同步发送消息

这篇博客主要就铺代码吧,Mina的一些基础知识可以参考:

http://www.cnblogs.com/huangfox/p/3458272.html

 

场景假设:

1.客户端发送用户信息,服务端根据用户名查询用户年龄。(模拟查询)

2.同步请求

3.协议:直接采用字段类型编码解码。

 


具体代码结构:

codec负责编码解码,TCPAcceptor服务端,TCPConnector客户端,User业务对象。

 


 

User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package  com.fox.mina.base.c2;
 
/**
  * @author huangfox
  * @date 2013年12月3日 上午11:23:55
  *
  */
public  class  User {
     String name;
     int  age;
 
     public  String getName() {
         return  name;
     }
 
     public  void  setName(String name) {
         this .name = name;
     }
 
     public  int  getAge() {
         return  age;
     }
 
     public  void  setAge( int  age) {
         this .age = age;
     }
 
     @Override
     public  String toString() {
         return  "User [name="  + name +  ", age="  + age +  "]" ;
     }
 
}

  

编码、解码工厂

DefaultMinaCodecFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package  com.fox.mina.base.c2.codec;
 
import  org.apache.mina.core.session.IoSession;
import  org.apache.mina.filter.codec.ProtocolCodecFactory;
import  org.apache.mina.filter.codec.ProtocolDecoder;
import  org.apache.mina.filter.codec.ProtocolEncoder;
 
/**
  * @author huangfox
  * @date 2013年12月5日 下午7:48:47
  *
  */
public  class  DefaultMinaCodecFactory  implements  ProtocolCodecFactory {
     ProtocolEncoder encoder;
     ProtocolDecoder decoder;
 
     public  DefaultMinaCodecFactory() {
 
     }
 
     public  DefaultMinaCodecFactory(ProtocolEncoder encoder,
             ProtocolDecoder decoder) {
         super ();
         this .encoder = encoder;
         this .decoder = decoder;
     }
 
     @Override
     public  ProtocolEncoder getEncoder(IoSession session)  throws  Exception {
         // TODO Auto-generated method stub
         return  encoder;
     }
 
     @Override
     public  ProtocolDecoder getDecoder(IoSession session)  throws  Exception {
         // TODO Auto-generated method stub
         return  decoder;
     }
 
     public  ProtocolEncoder getEncoder() {
         return  encoder;
     }
 
     public  void  setEncoder(ProtocolEncoder encoder) {
         this .encoder = encoder;
     }
 
     public  ProtocolDecoder getDecoder() {
         return  decoder;
     }
 
     public  void  setDecoder(ProtocolDecoder decoder) {
         this .decoder = decoder;
     }
 
}

  

编码器

FEncode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package  com.fox.mina.base.c2.codec;
 
import  org.apache.commons.lang.ArrayUtils;
import  org.apache.mina.core.buffer.IoBuffer;
import  org.apache.mina.core.session.IoSession;
import  org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import  org.apache.mina.filter.codec.ProtocolEncoderOutput;
 
import  com.fox.mina.base.c2.User;
 
/**
  * @author huangfox
  * @date 2013年12月5日 下午7:49:21
  *
  */
public  class  FEncoder  extends  ProtocolEncoderAdapter {
     public  static  final  NumberCodec numberCodec = DefaultNumberCodecs
             .getBigEndianNumberCodec();
 
     @Override
     public  void  encode(IoSession session, Object message,
             ProtocolEncoderOutput out)  throws  Exception {
         byte [] bytes =  null ;
         if  (message  instanceof  User) {
             User user = (User) message;
             byte [] name = user.getName().getBytes();
             bytes = ArrayUtils.addAll(bytes,
                     numberCodec.int2Bytes(name.length,  4 ));
             bytes = ArrayUtils.addAll(bytes, name);
             bytes = ArrayUtils.addAll(bytes,
                     numberCodec.int2Bytes(user.getAge(),  4 ));
             out.write(IoBuffer.wrap(bytes));
         else  {
             System.out.println( "encoder error!" );
         }
 
     }
 
}

编码的协议:

用户姓名的长度(int 4字节)

用户年龄(int 4字节)

用户姓名(byte[])

 

解码器

FDecode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package  com.fox.mina.base.c2.codec;
 
import  org.apache.mina.core.buffer.IoBuffer;
import  org.apache.mina.core.session.IoSession;
import  org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import  org.apache.mina.filter.codec.ProtocolDecoderOutput;
 
import  com.fox.mina.base.c2.User;
 
/**
  * @author huangfox
  * @date 2013年12月3日 上午11:35:46
  *
  */
public  class  FDecoder  extends  CumulativeProtocolDecoder {
     public  static  final  NumberCodec numberCodec = DefaultNumberCodecs
             .getBigEndianNumberCodec();
 
     @Override
     protected  boolean  doDecode(IoSession session, IoBuffer in,
             ProtocolDecoderOutput out)  throws  Exception {
         int  len =  0 ;
         Object lenAttr = session.getAttribute( "len" );
         if  (lenAttr ==  null ) {
             if  (in.remaining() <  4 ) {
                 return  false ;
             }
             byte [] buffer =  new  byte [ 4 ];
             in.get(buffer);
             len = numberCodec.bytes2Int(buffer,  4 );
             session.setAttribute( "len" , len);
         else  {
             len = (Integer) lenAttr;
         }
         //
         String name =  "" ;
         Object nameAttr = session.getAttribute( "name" );
         if  (nameAttr ==  null ) {
             if  (in.remaining() < len) {
                 return  false ;
             }
             byte [] buffer =  new  byte [len];
             in.get(buffer);
             name =  new  String(buffer);
             session.setAttribute( "name" , name);
         else  {
             name = (String) nameAttr;
         }
         if  (in.remaining() <  4 ) {
             return  false ;
         }
         byte [] buffer =  new  byte [ 4 ];
         in.get(buffer);
         int  age = numberCodec.bytes2Int(buffer,  4 );
         User u =  new  User();
         u.setName(name);
         u.setAge(age);
         //
         out.write(u);
         //
         session.removeAttribute( "len" );
         session.removeAttribute( "name" );
         
         return  true ;
     }
 
}

 

 

编码、解码使用的工具类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package  com.fox.mina.base.c2.codec;
 
public  interface  NumberCodec {
     String convertCharset(String charset);
 
     byte [] short2Bytes( short  value,  int  byteLength);
 
     byte [] int2Bytes( int  value,  int  byteLength);
 
     byte [] long2Bytes( long  value,  int  byteLength);
 
     byte [] float2Bytes( float  value,  int  byteLength);
 
     byte [] double2Bytes( double  value,  int  byteLength);
 
     short  bytes2Short( byte [] bytes,  int  byteLength);
 
     int  bytes2Int( byte [] bytes,  int  byteLength);
 
     long  bytes2Long( byte [] bytes,  int  byteLength);
 
     float  bytes2Float( byte [] bytes,  int  byteLength);
 
     double  bytes2Double( byte [] bytes,  int  byteLength);
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
package  com.fox.mina.base.c2.codec;
 
public  class  DefaultNumberCodecs {
 
     private  static  int  b2ui( byte  b) {
         return  ( int ) (b +  256 ) %  256 ;
     }
 
     private  static  long  b2ul( byte  b) {
         return  ( long ) (b +  256 ) %  256 ;
     }
 
     private  static  NumberCodec littleEndianCodec =  new  NumberCodec() {
 
         public  int  bytes2Int( byte [] bytes,  int  byteLength) {
             int  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ui(bytes[i]) << (i *  8 );
             }
             return  value;
         }
 
         public  long  bytes2Long( byte [] bytes,  int  byteLength) {
             long  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ul(bytes[i]) << (i *  8 );
             }
 
             return  value;
         }
 
         public  short  bytes2Short( byte [] bytes,  int  byteLength) {
             short  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ui(bytes[i]) << (i *  8 );
             }
 
             return  value;
         }
 
         @Override
         public  float  bytes2Float( byte [] bytes,  int  byteLength) {
             int  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ui(bytes[i]) << (i *  8 );
             }
             return  Float.intBitsToFloat(value);
         }
 
         @Override
         public  double  bytes2Double( byte [] bytes,  int  byteLength) {
             long  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ul(bytes[i]) << (i *  8 );
             }
             return  Double.longBitsToDouble(value);
         }
 
         public  byte [] int2Bytes( int  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = i *  8 ;
                 bytes[i] = ( byte ) ((value & ( 0x000000ff  << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         public  byte [] long2Bytes( long  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = i *  8 ;
                 bytes[i] = ( byte ) ((value & (0x00000000000000ffL << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         public  byte [] short2Bytes( short  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = i *  8 ;
                 bytes[i] = ( byte ) ((value & ( 0x00ff  << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         @Override
         public  byte [] float2Bytes( float  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             // parse the bits that represent the floating-point number
             // floatToRawIntBits gives the raw float bits without normalization
             // using floatToRawIntBits is over 5 times as fast as
             // floatToIntBits.
             int  x = Float.floatToRawIntBits(value);
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = i *  8 ;
                 bytes[i] = ( byte ) ((x & ( 0x000000ff  << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         @Override
         public  byte [] double2Bytes( double  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             // parse the the bits that represent the floating-point number
             long  x = Double.doubleToRawLongBits(value);
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = i *  8 ;
                 bytes[i] = ( byte ) ((x & (0x00000000000000ffL << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         public  String convertCharset(String charset) {
             if  (charset.equals( "UTF-16" )) {
                 return  "UTF-16LE" ;
             else  {
                 return  charset;
             }
         }
 
     };
 
     private  static  NumberCodec bigEndianCodec =  new  NumberCodec() {
 
         public  int  bytes2Int( byte [] bytes,  int  byteLength) {
             int  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ui(bytes[i]) << ((byteLength -  1  - i) *  8 );
             }
             return  value;
         }
 
         public  long  bytes2Long( byte [] bytes,  int  byteLength) {
             long  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ul(bytes[i]) << ((byteLength -  1  - i) *  8 );
             }
 
             return  value;
         }
 
         public  short  bytes2Short( byte [] bytes,  int  byteLength) {
             short  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ui(bytes[i]) << ((byteLength -  1  - i) *  8 );
             }
 
             return  value;
         }
 
         @Override
         public  float  bytes2Float( byte [] bytes,  int  byteLength) {
             int  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ui(bytes[i]) << ((byteLength -  1  - i) *  8 );
             }
             return  Float.intBitsToFloat(value);
         }
 
         @Override
         public  double  bytes2Double( byte [] bytes,  int  byteLength) {
             long  value =  0 ;
             for  ( int  i =  0 ; i < byteLength; i++) {
                 value |= b2ul(bytes[i]) << ((byteLength -  1  - i) *  8 );
             }
             return  Double.longBitsToDouble(value);
         }
 
         public  byte [] int2Bytes( int  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = ((byteLength -  1  - i) *  8 );
                 bytes[i] = ( byte ) ((value & ( 0x000000ff  << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         public  byte [] long2Bytes( long  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = ((byteLength -  1  - i) *  8 );
                 bytes[i] = ( byte ) ((value & (0x00000000000000ffL << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         public  byte [] short2Bytes( short  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = ((byteLength -  1  - i) *  8 );
                 bytes[i] = ( byte ) ((value & ( 0x00ff  << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         @Override
         public  byte [] float2Bytes( float  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             // parse the bits that represent the floating-point number
             // floatToRawIntBits gives the raw float bits without normalization
             // using floatToRawIntBits is over 5 times as fast as
             // floatToIntBits.
             int  x = Float.floatToRawIntBits(value);
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = ((byteLength -  1  - i) *  8 );
                 bytes[i] = ( byte ) ((x & (0x000000ffL << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         @Override
         public  byte [] double2Bytes( double  value,  int  byteLength) {
             byte [] bytes =  new  byte [byteLength];
 
             // parse the the bits that represent the floating-point number
             long  x = Double.doubleToRawLongBits(value);
             for  ( int  i =  0 ; i < byteLength; i++) {
                 int  shiftCount = ((byteLength -  1  - i) *  8 );
                 bytes[i] = ( byte ) ((x & (0x00000000000000ffL << shiftCount)) >> shiftCount);
             }
             return  bytes;
         }
 
         public  String convertCharset(String charset) {
             if  (charset.equals( "UTF-16" )) {
                 return  "UTF-16BE" ;
             else  {
                 return  charset;
             }
         }
 
     };
 
     public  static  NumberCodec getBigEndianNumberCodec() {
         return  bigEndianCodec;
     }
 
     public  static  NumberCodec getLittleEndianNumberCodec() {
         return  littleEndianCodec;
     }
}

  

服务端

TCPAcceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package  com.fox.mina.base.c2;
 
import  java.io.IOException;
import  java.net.InetSocketAddress;
 
import  org.apache.mina.core.service.IoAcceptor;
import  org.apache.mina.core.service.IoHandlerAdapter;
import  org.apache.mina.core.session.IoSession;
import  org.apache.mina.core.session.IoSessionConfig;
import  org.apache.mina.filter.codec.ProtocolCodecFilter;
import  org.apache.mina.transport.socket.nio.NioSocketAcceptor;
 
import  com.fox.mina.base.c2.codec.DefaultMinaCodecFactory;
import  com.fox.mina.base.c2.codec.FDecoder;
import  com.fox.mina.base.c2.codec.FEncoder;
 
/**
  * @author huangfox
  * @date 2013年12月3日 上午11:15:53
  *
  */
public  class  TCPAcceptor {
     IoAcceptor acceptor =  null ;
     String addr =  "127.0.0.1" ;
     int  port =  9999 ;
 
     public  TCPAcceptor() {
 
     }
 
     public  void  start() {
         acceptor =  new  NioSocketAcceptor();
         //
         IoSessionConfig sessionConf = acceptor.getSessionConfig();
         sessionConf.setReadBufferSize( 2048 );
         // filter chain(codec)
         acceptor.getFilterChain().addLast(
                 "codec" ,
                 new  ProtocolCodecFilter( new  DefaultMinaCodecFactory(
                         new  FEncoder(),  new  FDecoder())));
         // handler
         acceptor.setHandler( new  IOHandler());
         //
         try  { // 可做重连
             acceptor.bind( new  InetSocketAddress(addr, port));
         catch  (IOException e) {
             e.printStackTrace();
         }
         System.out.println( "server stated ... " );
     }
 
     private  class  IOHandler  extends  IoHandlerAdapter {
 
         @Override
         public  void  messageReceived(IoSession session, Object message)
                 throws  Exception {
             User u = (User) message;
             System.out.println( "[server]"  + u.toString());
             //模拟业务处理
             u.setAge(u.hashCode()% 100 );
             // send msg to client
             session.write(u);
         }
 
     }
 
     public  static  void  main(String[] args) {
         TCPAcceptor server =  new  TCPAcceptor();
         server.start();
     }
 
}

  

客户端

TCPConnector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package  com.fox.mina.base.c2;
 
import  java.io.BufferedReader;
import  java.io.IOException;
import  java.io.InputStreamReader;
import  java.net.InetSocketAddress;
import  java.util.Random;
 
import  org.apache.mina.core.future.ConnectFuture;
import  org.apache.mina.core.future.ReadFuture;
import  org.apache.mina.core.future.WriteFuture;
import  org.apache.mina.core.service.IoConnector;
import  org.apache.mina.core.service.IoHandlerAdapter;
import  org.apache.mina.core.session.IoSession;
import  org.apache.mina.filter.codec.ProtocolCodecFilter;
import  org.apache.mina.transport.socket.nio.NioSocketConnector;
 
import  com.fox.mina.base.c2.codec.DefaultMinaCodecFactory;
import  com.fox.mina.base.c2.codec.FDecoder;
import  com.fox.mina.base.c2.codec.FEncoder;
 
/**
  * @author huangfox
  * @date 2013年12月3日 上午11:15:46
  *
  */
public  class  TCPConnector {
     IoConnector connector =  null ;
     IoSession session =  null ;
     String ip =  "127.0.0.1" ;
     int  port =  9999 ;
 
     public  TCPConnector() {
         connector =  new  NioSocketConnector();
         connector.getSessionConfig().setUseReadOperation( true );
         connector.getFilterChain().addLast(
                 "codec" ,
                 new  ProtocolCodecFilter( new  DefaultMinaCodecFactory(
                         new  FEncoder(),  new  FDecoder())));
         connector.setHandler( new  IOHander());
         ConnectFuture connectF = connector.connect( new  InetSocketAddress(ip,
                 port));
         connectF.awaitUninterruptibly();
         session = connectF.getSession();
     }
 
     Random r =  new  Random();
 
     public  void  sendMsg(User u) {
         WriteFuture writeF = session.write(u);
         writeF.awaitUninterruptibly();
         if  (writeF.getException() !=  null ) {
             System.out.println(writeF.getException().getMessage());
         else  if  (writeF.isWritten()) {
             System.out.println( "msg was sent!" );
             // 发送、接受
             ReadFuture readF = session.read();
             readF.awaitUninterruptibly( 1000 );
             if  (readF.getException() !=  null ) {
                 System.out.println(readF.getException().getMessage());
             else  {
                 System.out.println( "[client]" +readF.getMessage().toString());
             }
         else  {
             System.out.println( "error!" );
         }
     }
 
     public  void  close() {
         this .connector.dispose();
     }
 
     private  class  IOHander  extends  IoHandlerAdapter {
 
     }
 
     public  static  void  main(String[] args) {
         TCPConnector client =  new  TCPConnector();
         while  ( true ) {
             BufferedReader r =  new  BufferedReader( new  InputStreamReader(
                     System.in));
             try  {
                 System.out.println( "输入:" );
                 String msg = r.readLine();
                 User u =  new  User();
                 u.setName(msg);
                 client.sendMsg(u);
             catch  (IOException e) {
                 e.printStackTrace();
             }
 
         }
     }
 
     
}

 


注意:以上代码在多线程环境下是有问题的!!!  

(最大字体的提示了!)

在TcpConnector中,只有一个session,如果多线程同时对这个session进行读写操作将发生问题(B可能拿到A的响应结果)。

最简单的处理方式就是,加入一个连接池,在sendMsg方法中先获取一个连接,用完以后再归还到连接池。可以理解为“一个线程独占一个连接”。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package  com.fox.mina.base.c2;
 
import  java.net.InetSocketAddress;
import  java.util.Date;
import  java.util.Random;
import  java.util.concurrent.LinkedBlockingQueue;
import  java.util.concurrent.TimeUnit;
 
import  org.apache.mina.core.future.ConnectFuture;
import  org.apache.mina.core.future.ReadFuture;
import  org.apache.mina.core.future.WriteFuture;
import  org.apache.mina.core.service.IoConnector;
import  org.apache.mina.core.service.IoHandlerAdapter;
import  org.apache.mina.core.session.IoSession;
import  org.apache.mina.filter.codec.ProtocolCodecFilter;
import  org.apache.mina.transport.socket.nio.NioSocketConnector;
 
import  com.fox.mina.base.c2.codec.DefaultMinaCodecFactory;
import  com.fox.mina.base.c2.codec.FDecoder;
import  com.fox.mina.base.c2.codec.FEncoder;
 
/**
  * @author huangfox
  * @date 2013年12月3日 上午11:15:46
  *
  */
public  class  TCPConnector {
     IoConnector connector =  null ;
     // IoSession session = null;
     String ip =  "127.0.0.1" ;
     int  port =  9999 ;
     int  poolSize =  1 ;
     LinkedBlockingQueue<IoSession> pool;
 
     public  TCPConnector() {
         connector =  new  NioSocketConnector( 10 );
         connector.getSessionConfig().setUseReadOperation( true );
         connector.getFilterChain().addLast(
                 "codec" ,
                 new  ProtocolCodecFilter( new  DefaultMinaCodecFactory(
                         new  FEncoder(),  new  FDecoder())));
         connector.setHandler( new  IOHander());
         // pool
         pool =  new  LinkedBlockingQueue<IoSession>(poolSize);
         for  ( int  i =  0 ; i < poolSize; i++) {
             ConnectFuture connectF = connector.connect( new  InetSocketAddress(
                     ip, port));
             connectF.awaitUninterruptibly();
             IoSession session = connectF.getSession();
             try  {
                 pool.put(session);
             catch  (InterruptedException e) {
                 e.printStackTrace();
             }
         }
     }
 
     Random r =  new  Random();
 
     public  void  sendMsg(User u) {
         IoSession session =  null ;
         try  {
             session = pool.take();
         catch  (InterruptedException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         if  (session ==  null )
             return ;
         try  {
             WriteFuture writeF = session.write(u);
             writeF.awaitUninterruptibly();
             if  (writeF.getException() !=  null ) {
                 System.out.println(writeF.getException().getMessage());
             else  if  (writeF.isWritten()) {
                 // System.out.println("msg was sent!");
                 // 发送、接受
                 ReadFuture readF = session.read();
                 readF.awaitUninterruptibly();
                 if  (readF.getException() !=  null ) {
                     System.out.println(readF.getException().getMessage());
                 else  {
                     Date d =  new  Date(System.currentTimeMillis());
                     // System.out.println(Thread.currentThread().getId() + "-"
                     // + d.getSeconds() + "-" + session.hashCode());
                     // System.out.println("[client]"
                     // + readF.getMessage().toString());
                 }
             else  {
                 System.out.println( "error!" );
             }
         finally  {
             try  {
                 pool.put(session);
             catch  (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
     }
 
     public  void  close() {
         this .connector.dispose();
     }
 
     private  class  IOHander  extends  IoHandlerAdapter {
 
     }
 
}

  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值