Mina服务端 Python客户端使用Json数据传递
最近在做一个项目,需要进行客户端服务器数据交互,由于项目需要,服务器使用Mina框架编写,而客户端使用Python编写。
在这里就不多讲关于Mina的框架结构了,相关的blog挺多,如果有兴趣可以查看这篇blog关于Mina框架的解释。
Mina服务器端
项目使用的是apache-mina-2.0.9,下载之后全导入项目就ok。
而解析Json使用的是org.json包
(1)Mina服务端由两部分组成,一部分是初始化在MinaServer.java中,而主要需要自定义的是ServerHandler.java中的代码。
(2)ServerHandler 继承IoHandlerAdapter,其中messageReceived函数在接受到消息时会被调用,在这里要注意初始化时候的调用的过滤器,其中”codec”过滤器是负责解码编码的,需要注意的是,当使用默认配置时,此过滤器判定结尾符号为’\n’,若没有接收到此符号则不会判定接收完成,不管客户端发送多少次,messageReceived函数都不会得到响应。
当然可以对过滤器进行自定义只需要继承IoFilterAdapter,因为本文中没有涉及这个方面,所以具体方法这里就不多说了。
(3)对于接收到的Json字符串,则用JSONObject request = new JSONObject(message.toString())转换为Json对象。
MinaServer.java代码
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class MinaServer {
private static final int PORT = 9123;
public static void main( String[] args ) throws IOException
{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "ASCII" ))));
acceptor.setHandler( new TimeServerHandler() );
acceptor.getSessionConfig().setReadBufferSize( 2048 );
acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
acceptor.bind( new InetSocketAddress(PORT) );
}
}
ServerHandler.java代码
import java.util.Date;
import org.json.*;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
public class ServerHandler extends IoHandlerAdapter {
@Override
public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
{
cause.printStackTrace();
}
@Override
public void messageReceived( IoSession session, Object message ) throws Exception
{
JSONObject request = new JSONObject(message.toString());
String str = message.toString();
if( str.trim().equalsIgnoreCase("quit") ) {
session.close();
return;
}
System.out.println(str);
}
@Override
public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
{
System.out.println( "IDLE " + session.getIdleCount( status ));
}
}
Python客户端
Python编写的客户端非常简单,没有使用任何框架,只是使用Scoket套接字进行初始化。
而对Json的对象化使用json.dumps()函数就能轻松完成,而在对象化之前,是Python的字典数组。
特别注意的是发送Json字符串后需要再发送一个’\n’换行符,因为服务端解码时是将换行符作为结束符。
import sys
import socket
import json
class Myscoket():
def __init__(self,argv):
self.desIP=argv[1]
self.desPort=argv[2]
def socket_init(self):
self.s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.connect((self.desIP,int(self.desPort)))
def recive_Msg(self):
return self.s.recv(1024)
def send_Msg(self,msg):
self.s.send(msg)
def JsonSerialize(data):
Jsondata=json.dumps(data)
return Jsondata
def JsonDeserialize(Jsondata):
data=json.loads(Jsondata)
return data
data={'ID':'1001','bool':False}
Jsondata=JsonSerialize(data)
m=Myscoket(sys.argv)
m.socket_init()
m.send_Msg(Jsondata)
m.send_Msg('\n')