Mina框架中使用Socket的例子,包括服务端和客户端。

最近研究了一下socket,以前是直接用的,感觉总不好,后来前辈给我介绍了mina。这个框架已经封装好了socket,非常方便,比起直接用socket来说优越性高点。

下面准备客户端和服务端的例子,以及写好的服务端打包成exe文件,运行在服务器上。

先贴下运行效果:


1、服务端的项目:

使用的开发工具是myeclipse。项目中引用了hibernate3.3,只要用来访问本地的sql server数据库,具体如何配置去连接数据库,等会也会说。

项目结构:


数据库配置图片太多了,不会就看我的文档!!!sql server和hibernate的配置都在这个文档里面,需要请下载  sql server 数据库配置。

要使用mina,必须添加mina-core和slf4j-api.jar 包。

与mina相关的类是:MainServer和ServerHandler这两个类。

ServerHandler类:

package com.org.mina;

import java.util.ArrayList;
import java.util.List;

import org.apache.mina.core.filterchain.IoFilterAdapter;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.org.dao.FileUpdataDao;
import com.org.dao.impl.FileUpdataDaoImpl;
import com.org.entity.FileData;


public class ServerHandler extends IoFilterAdapter implements IoHandler {

	
	private FileUpdataDao impl = new FileUpdataDaoImpl();
	
private static ServerHandler samplMinaServerHandler = null;     
    
    public static ServerHandler getInstances() {     
        if (null == samplMinaServerHandler) {     
            samplMinaServerHandler = new ServerHandler();     
        }     
        return samplMinaServerHandler;     
    }     
    
    private ServerHandler() {     
    
    }

	@Override
	public void exceptionCaught(IoSession arg0, Throwable arg1)
			throws Exception {
		System.out.println("exceptionCaught");
	}

	@Override
	public void messageReceived(IoSession session, Object message) throws Exception {
		System.out.println("messageReceived");
		
		System.out.println("message->"+(String)message);
	}

	@Override
	public void messageSent(IoSession arg0, Object arg1) throws Exception {
		System.out.println("messageSent");
	}

	@Override
	public void sessionClosed(IoSession arg0) throws Exception {
		System.out.println("sessionClosed");
	}

	@Override
	public void sessionCreated(IoSession arg0) throws Exception {
		System.out.println("sessionCreated");
	}

	@Override
	public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {
		System.out.println("sessionIdle");
	}

	@Override
	public void sessionOpened(final IoSession session) throws Exception {
		System.out.println("sessionOpened");
		//不停访问数据库某个表
//	     Thread thread = new Thread(new myThread(session));   
//	     thread.start();
		
		session.write("服务端向客户端发送来消息:hello!");
	}     
    
	
	
	
    public class myThread implements Runnable{
    	private IoSession session;
    	public myThread(IoSession session){
    		this.session = session;
    	}
    	
		@Override
		public void run() {
			
			while(true){
			try {
				String hql = "from FileData";
		        List<FileData> datalist = impl.getList(hql);
				
				JSONObject Jsonobject = new JSONObject();
				JSONArray JsonArray = new JSONArray();
				for(int i = 0;i<datalist.size();i++)
				{
					FileData fileData = (FileData)datalist.get(i);
					JSONObject object = new JSONObject();
					object.put("info_no", fileData.getInfoNo());
					object.put("File_Type_name", fileData.getFileTypeName());
					object.put("Insert_Operator", fileData.getInsertOperator());
					JsonArray.put(object);
				}
				
				Jsonobject.put("FileData", JsonArray);
				
				session.write(Jsonobject.toString());
				
				System.out.println(Jsonobject.toString());
				
				Thread.sleep(3000);
				
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			}
			}
		}
    	
    }
	
}

MainServer类:

package com.org.mina;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.List;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.json.JSONArray;
import org.json.JSONObject;

import com.org.dao.FileUpdataDao;
import com.org.dao.impl.FileUpdataDaoImpl;
import com.org.entity.FileData;

public class MainServer {     
    private static MainServer mainServer = null;     
    private SocketAcceptor acceptor = new NioSocketAcceptor();     
    private DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();     
    private int bindPort = 4000;     
    
    
    public static MainServer getInstances() {     
        if (null == mainServer) {     
            mainServer = new MainServer();     
        }     
        return mainServer;     
    }     
    
    private MainServer() {     
        chain.addLast("myChin", new ProtocolCodecFilter(     
                new ObjectSerializationCodecFactory()));     
        acceptor.setHandler(ServerHandler.getInstances());     
        try {     
            acceptor.bind(new InetSocketAddress(bindPort));     
        } catch (IOException e) {     
            e.printStackTrace();     
        }     
    }     
    
    public static void main(String[] args) throws Exception {     
        MainServer.getInstances();  
        
        System.out.println("mainServer!!!!!!!!!!!!!");
        
    }     
}   

程序入口是:运行MainServer类!

2、客户端的项目

项目结构如图,android客户端所添加的slf4j-android.jar,是这个。

关于mina的类:ClientHandler ,MainClient 和MainActivity类。MainClient 用来测试用,程序入口是MainActivity类。

ClientHandler类:

package com.org.mina;


import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

import android.content.Context;
import android.content.Intent;

public class ClientHandler extends IoHandlerAdapter {     

	private Context context;
	
//    private static ClientHandler samplMinaClientHandler = null;     
    /*public static ClientHandler getInstances(Context context) {     
        if (null == samplMinaClientHandler) {     
        	
        	context = context;
            samplMinaClientHandler = new ClientHandler(context);     
        }     
        return samplMinaClientHandler;     
    }     */
    
   
    
    public ClientHandler(Context context) {
		this.context = context;
//		samplMinaClientHandler = new ClientHandler(context);  
	}



	public void sessionOpened(IoSession session) throws Exception {     
    	System.out.println("sessionOpened");
    }     
    
    public void sessionClosed(IoSession session) {    
    	System.out.println("sessionClosed");
    }     
    
    public void messageReceived(IoSession session, Object message)     
            throws Exception { 	
    	Intent intent = new Intent();
		intent.setAction("com.mina.broadcast");
		intent.putExtra("message", (String)message);
		context.sendBroadcast(intent);
    }     
    
    public void messageSent(IoSession arg0, Object arg1) throws Exception {  
    	System.out.println("messageSent");
    }


	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		
		super.exceptionCaught(session, cause);
		
	}  
  
}    

MainActivity类:

package com.org.mina;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.HashMap;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;


import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Menu;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class MainActivity extends Activity{

	private ListView listView;
	
	private SimpleAdapter simpleAdapter;
	
	private ArrayList<HashMap<String, Object>> listItem;
	
    private NioSocketConnector connector = new NioSocketConnector();     
    private DefaultIoFilterChainBuilder chain = connector.getFilterChain();
    
   /* private Handler handler = new Handler(){

		@Override
		public void handleMessage(Message msg) {
			try {
				listItem = new ArrayList<HashMap<String,Object>>();
				
				JSONObject jsonObject = new JSONObject(msg.obj.toString());
				JSONArray jsonArray = jsonObject.getJSONArray("FileData");
				for(int i = 0;i<jsonArray.length();i++)
				{
					JSONObject object = (JSONObject) jsonArray.get(i);
					HashMap<String, Object> map = new HashMap<String, Object>();  
		            map.put("info_no", object.get("info_no"));  
		            map.put("fileName", object.get("File_Type_name"));  
		            map.put("Insert_Operator", object.get("Insert_Operator"));  
		            listItem.add(map);
				}
				simpleAdapter.notifyDataSetChanged();
				
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
    	
    };*/
    
    private BroadcastReceiver PriceReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
	        if(intent.getAction().equals("com.mina.broadcast"))
	        { 
	        	String msg = intent.getStringExtra("message");
	        	try {
	        		
	        	listItem.clear();
	        		
	        	JSONObject jsonObject = new JSONObject(msg);
				JSONArray jsonArray = jsonObject.getJSONArray("FileData");
				for(int i = 0;i<jsonArray.length();i++)
				{
					JSONObject object = (JSONObject) jsonArray.get(i);
					HashMap<String, Object> map = new HashMap<String, Object>();  
		            map.put("info_no", object.get("info_no"));  
		            map.put("fileName", object.get("File_Type_name"));  
		            map.put("Insert_Operator", object.get("Insert_Operator"));  
		            listItem.add(map);
				}
				simpleAdapter.notifyDataSetChanged();
				
	        	} catch (JSONException e) {
					e.printStackTrace();
				}
	        }
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		java.lang.System.setProperty("java.net.preferIPv4Stack", "true"); 
		java.lang.System.setProperty("java.net.preferIPv6Addresses", "false");
		
		setContentView(R.layout.activity_main);
		listView = (ListView) findViewById(R.id.listView);
		listItem = new ArrayList<HashMap<String,Object>>();
		simpleAdapter = new SimpleAdapter (this,listItem,R.layout.listitem, 
				new String[]{"info_no","fileName","Insert_Operator"}, 
				new int[]{R.id.textView01,R.id.textView02,R.id.textView03});
		listView.setAdapter(simpleAdapter);
		
		new Thread(new Runnable(){
			@Override
			public void run() {
			 
				chain.addLast("myChin", new ProtocolCodecFilter(     
		                new ObjectSerializationCodecFactory()));   
				
				ClientHandler clientHandler = new ClientHandler(MainActivity.this);
		        connector.setHandler(clientHandler);     
		        connector.setConnectTimeout(30);     
		        ConnectFuture cf = connector.connect(new InetSocketAddress("192.168.1.104",4000));   
				
		        cf.join();
		        
		       System.out.println("isConnected:"+cf.isConnected());
		        
		        if(!cf.isConnected())
		        {
		        	System.out.println("连接服务器失败!!!");
		        }
		        else
		        {
		        	System.out.println("连接成功!!!");
		        }
			}
			}).start(); 
		
		
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public void close() {
		Intent i = new Intent();
		i.setAction("com.mina.broadcast");
		sendBroadcast(i);
		finish();
	}

	@Override
	protected void onStart() {
		super.onStart();
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction("com.mina.broadcast");
		registerReceiver(PriceReceiver, intentFilter);
	}

	@Override
	protected void onStop() {
		super.onStop();
		unregisterReceiver(PriceReceiver);
	}
	
	
}

要注意配置服务器的端口,客户端的ip和端口,ip就是运行服务端的电脑IP。

先运行服务端Mainserver,再运行客服端的MainActivity,就可以了。

服务端和客户端项目下载地址是:mina项目的下载链接  

上面就告一段落。不懂的可以提问!!


还有点问题,当多个客户端访问一个服务端时,要保存生成的session,才能给各个会话发送消息,例如:

Collection<IoSession> sessions = session.getService().getManagedSessions().values();  
                    for (IoSession sess : sessions)
                    {  
                         sess.write(result);  
                         textArea.append("第 "+sess.getId()+" 个会话发送的消息:"+result+"\n");
                     }

但是这样子的话,服务端很容易崩溃!!!不知道有谁用mina socket写过服务端,至少不会那么容易崩溃的说,有的话请告诉我,谢谢!


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值