创建java项目,导入mina包。mina下载地址:http://mina.apache.org/
不会用mina的请各种百度谷歌吧。。
新建MainServer.java类,继承于Thread并实现main函数。
然后就在MainServer类里搭建main结构啦。
类如下:
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
|
import
handler.MainHandler;
import
java.net.InetSocketAddress;
import
org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import
org.apache.mina.filter.codec.ProtocolCodecFilter;
import
org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import
coder.buffer.BufferCoderFactory;
/**
* @author duwei
* @since 2013.10.25
*
* */
public
class
MainServer
extends
Thread{
//the mina info
public
boolean
isAlive =
true
;
public
MainHandler handler;
public
NioSocketAcceptor socketAcceptor;
public
final
int
port =
8005
;
//database info
public
static
String dbHost=
"192.168.1.103"
,dbName=
"test"
,username=
"work"
,password=
"123456"
;
public
static
int
dbPort =
3306
;
public
MainServer(){
super
(
"MainServer"
);
socketAcceptor =
new
NioSocketAcceptor();
socketAcceptor.setReuseAddress(
true
);
socketAcceptor.getSessionConfig().setKeepAlive(
true
);
handler =
new
MainHandler();
socketAcceptor.setHandler(handler);
//设置过滤器
DefaultIoFilterChainBuilder chain = socketAcceptor.getFilterChain();
chain.addLast(
"codec"
,
new
ProtocolCodecFilter(
new
BufferCoderFactory()));
//明码字符串
//启动数据库
startDataBaseDriver(dbHost, dbPort, dbName, username, password);
}
public
void
run(){
while
(isAlive){
try
{
sleep(
3000
);
}
catch
(Exception e) {
// TODO: handle exception
}
}
System.exit(
0
);
}
private
void
startDataBaseDriver(String host,
int
port,String dbName,String username,String password){
try
{
}
catch
(Exception e) {
e.printStackTrace();
}
}
public
void
startAcceptor(){
try
{
socketAcceptor.bind(
new
InetSocketAddress(port));
this
.start();
}
catch
(Exception e) {
e.printStackTrace();
}
}
/**
* @param args
*/
public
static
void
main(String[] args) {
//start mina and database
MainServer main =
new
MainServer();
main.startAcceptor();
System.out.println(
"server started finished @ 192.168.1.122:8005"
);
}
}
|
从上述代码中可见,需要建立一个编解码工厂和一个实现IOHandler接口的实例啦,因为IOHandler接口是负责处理所有业务逻辑的啦。
所谓编解码工厂,就是一个负责在发送数据的最后阶段和接收数据的最开始阶段处理所发送和接收的数据。
比如:服务端发送一段数据是:“数据长度(4字节)+实际数据”,那么接收到数据后就会首先读取4个字节的长度信息验证后面的实际数据有木有这么多。完了再从IoBuffer里解析出来写入ProtocolDecoderOutput里。发送数据也是类似,在session.write("...");发送数据后,会进入ProtocolEncoder实例里对数据经行封装。比如说加密,加压等操作。
java代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package
coder.buffer;
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;
public
class
BufferCoderFactory
implements
ProtocolCodecFactory {
private
ProtocolEncoder encoder;
private
ProtocolDecoder decoder;
@Override
public
ProtocolDecoder getDecoder(IoSession arg0)
throws
Exception {
// TODO Auto-generated method stub
decoder =
new
BufferDecoder();
return
decoder;
}
@Override
public
ProtocolEncoder getEncoder(IoSession arg0)
throws
Exception {
// TODO Auto-generated method stub
encoder =
new
BufferEncoder();
return
encoder;
}
}
|
编码类:
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
|
package
coder.buffer;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
java.util.zip.Deflater;
import
org.apache.mina.core.buffer.IoBuffer;
import
org.apache.mina.core.session.AttributeKey;
import
org.apache.mina.core.session.IoSession;
import
org.apache.mina.filter.codec.ProtocolEncoder;
import
org.apache.mina.filter.codec.ProtocolEncoderOutput;
public
class
BufferEncoder
implements
ProtocolEncoder{
private
final
AttributeKey DEFLATER =
new
AttributeKey(getClass(),
"deflater"
);
private
static
int
buffersize =
1024
;
public
void
encode(IoSession session, Object in, ProtocolEncoderOutput out)
throws
Exception{
if
(in
instanceof
String){
byte
[] bytes = ((String) in).getBytes(
"utf-8"
);
System.out.println(
"压缩前:"
+bytes.length);
bytes = compress(session, bytes);
System.out.println(
"压缩后:"
+bytes.length);
IoBuffer buffer = IoBuffer.allocate(bytes.length +
4
);
buffer.putInt(bytes.length);
buffer.put(bytes);
buffer.flip();
session.write(buffer);
buffer.free();
}
else
{
System.out.println(
"message is not a String instance."
);
}
}
private
byte
[] compress(IoSession session,
byte
[] inputs){
Deflater deflater = (Deflater)session.getAttribute(DEFLATER);
if
(deflater ==
null
){
deflater =
new
Deflater();
session.setAttribute(DEFLATER,deflater);
}
deflater.reset();
deflater.setInput(inputs);
deflater.finish();
byte
[] outputs =
new
byte
[
0
];
ByteArrayOutputStream stream =
new
ByteArrayOutputStream(inputs.length);
byte
[] bytes =
new
byte
[buffersize];
int
value;
while
(!deflater.finished()){
value = deflater.deflate(bytes);
stream.write(bytes,
0
, value);
}
outputs = stream.toByteArray();
try
{
stream.close();
}
catch
(IOException e) {
e.printStackTrace();
}
return
outputs;
}
public
void
dispose(IoSession paramIoSession)
throws
Exception{
}
}
|
解码类:
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
|
package
coder.buffer;
import
org.apache.mina.core.buffer.IoBuffer;
import
org.apache.mina.core.session.IoSession;
import
org.apache.mina.filter.codec.ProtocolDecoder;
import
org.apache.mina.filter.codec.ProtocolDecoderOutput;
public
class
BufferDecoder
implements
ProtocolDecoder{
public
static
final
int
MAX_MSG_SIZE =
5000
;
public
void
decode(IoSession paramIoSession, IoBuffer in, ProtocolDecoderOutput out)
throws
Exception{
if
(in.prefixedDataAvailable(
4
, MAX_MSG_SIZE)) {
int
length = in.getInt();
byte
[] bytes =
new
byte
[length];
in.get(bytes);
out.write(bytes);
}
else
{
}
}
@Override
public
void
dispose(IoSession arg0)
throws
Exception {
// TODO Auto-generated method stub
}
@Override
public
void
finishDecode(IoSession arg0, ProtocolDecoderOutput arg1)
throws
Exception {
// TODO Auto-generated method stub
}
}
|
2.编码完成后,数据就会交给IOHandler来处理啦,这里可以选择继承IoHandlerAdapter类来写。。
IOHandler接口的几个重要方法介绍:
sessionCreated:一个连接被创建时触发;
sessionOpened:一个连接被打开时触发;
sessionClosed:一个连接被关闭时触发;
exceptionCaught:连接出现异常未被捕获时触发;
messageReceived:连接收到消息时触发。
好了,接下来实现自己的Handler实例:
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
handler;
import
org.apache.mina.core.service.IoHandlerAdapter;
import
org.apache.mina.core.session.IoSession;
public
class
MainHandler
extends
IoHandlerAdapter{
public
void
sessionOpened(IoSession session)
throws
Exception {
System.out.println(
"session opened "
+session.getRemoteAddress().toString());
}
public
void
messageReceived(IoSession session, Object message)
throws
Exception{
String str =
new
String((
byte
[]) message,
"utf8"
);
//收到客户端发来的数据
System.out.println(
"received message: "
+str);
//向客户端发送数据
session.write(
"fuck you too."
);
}
public
void
sessionClosed(IoSession session)
throws
Exception {
System.out.println(
"session closed "
+session.getRemoteAddress().toString());
}
public
void
exceptionCaught(IoSession session, Throwable cause)
throws
Exception {
System.out.println(
"exceptionCaught"
);
cause.printStackTrace();
}
}
|
好了,目前这个没有连接数据库的mina服务端就算是勉强搭建好了,运行一下试试??
和你的客户端勾兑一下,看看有木有勾搭上~~ 哈哈~~
本人新手,也不太熟悉java服务端。。
如果有什么问题,么见怪哈。大家一起探讨,一起研究,一起进步。~~