这几天刚学期android,目前项目要求的客户端是android平台,所以要开始啃了....
服务器与客户端的通信准备使用现有的开发框架,找了几个----mina,google 的 protobuf,smack,androidpn,Netty...
这些框架都不错,不过最终选择的是apache的mina框架,主要是mina在网上的资料比较全,用的也比较广泛,再就是也适合我项目以后的扩展加入SPRING\CXF\RESTFUL WEBSERVICE等
不废话了,开始把目前学习的进度开始进行整理,方便自己以后进行查阅,也给其他入门的兄弟们 参考参考。
当然,最重要的是希望大家能够提出并给与宝贵的经验。
服务端代码:
package org.demo;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Demo1Server {
private static Logger logger = LoggerFactory.getLogger(Demo1Server.class);
private static int PORT = 8989;
public static void main(String[] args) {
IoAcceptor acceptor = null;
try {
// 创建一个非阻塞的server端的Socket
acceptor = new NioSocketAcceptor();
// 设置过滤器(使用Mina提供的文本换行符编解码器)
acceptor.getFilterChain().addLast(
"codec",
new ProtocolCodecFilter(new TextLineCodecFactory(Charset
.forName("UTF-8"),
LineDelimiter.WINDOWS.getValue(),
LineDelimiter.WINDOWS.getValue())));
// 设置读取数据的缓冲区大小
acceptor.getSessionConfig().setReadBufferSize(2048);
// 读写通道10秒内无操作进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
// 绑定逻辑处理器
acceptor.setHandler(new Demo1ServerHandler());
// 绑定端口
acceptor.bind(new InetSocketAddress(PORT));
logger.info("服务端启动成功... 端口号为:" + PORT);
} catch (Exception e) {
logger.error("服务端启动异常....", e);
e.printStackTrace();
}
}
}
逻辑处理:
package org.demo;
import java.util.Date;
import net.sf.json.JSONObject;
import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoProcessor;
import org.apache.mina.common.IoSession;
import org.apache.mina.transport.socket.nio.NioProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Demo1ServerHandler extends IoHandlerAdapter{
public static Logger logger = LoggerFactory.getLogger(Demo1ServerHandler.class);
/**
* 这个方法当一个Session 对象被创建的时候被调用。对于TCP 连接来说,连接被接受的时候
* 调用,但要注意此时TCP 连接并未建立,此方法仅代表字面含义,也就是连接的对象
* IoSession 被创建完毕的时候,回调这个方法。
* 对于UDP 来说,当有数据包收到的时候回调这个方法,因为UDP 是无连接的。
*/
@Override
public void sessionCreated(IoSession session) throws Exception {
logger.info("服务端与客户端创建连接...");
}
/**
* 这个方法在连接被打开时调用,它总是在sessionCreated()方法之后被调用。对于TCP 来
* 说,它是在连接被建立之后调用,你可以在这里执行一些认证操作、发送数据等。
*/
@Override
public void sessionOpened(IoSession session) throws Exception {
logger.info("服务端与客户端连接打开...");
}
/**
* 接收到消息时调用的方法,也就是用于接收消息的方法,一般情况下,message 是一个
* IoBuffer 类,如果你使用了协议编解码器,那么可以强制转换为你需要的类型。
*/
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
/*
String msg = message.toString();
//读取数据
logger.info("服务端接收到的数据为:" + msg+"客户端ip:"+session.getLocalAddress());
if ("bye".equals(msg)) { // 服务端断开连接的条件
session.close();
}
Date date = new Date();
session.write(date);*/
JSONObject jsonObject = JSONObject.fromObject(message.toString());
String username;
String sex;
String qq;
String score;
String nickname;
username = jsonObject.getString("username");
sex = jsonObject.getString("sex");
qq = jsonObject.getString("QQ");
score = jsonObject.getString("Min.score");
nickname = jsonObject.getString("nickname");
int state = login(username);
String msg = "登录成功!";
if(state == 0){
msg = "登录失败!";
}
logger.info("用户:" + username + msg);
//模拟登陆
if ("bye".equals(nickname)) { // 服务端断开连接的条件
session.close();
}
//Date date = new Date();
session.write(state);
}
//验证用户名 与 密码
public int login(String message){
if("sysadmin".equals(message)){
return 1;
}
return 0;
}
/**
* 当发送消息成功时调用这个方法,注意这里的措辞,发送成功之后,
* 也就是说发送消息是不能用这个方法的。
*/
@Override
public void messageSent(IoSession session, Object message) throws Exception {
logger.info("服务端发送信息成功...");
}
/**
* 对于TCP 来说,连接被关闭时,调用这个方法。
* 对于UDP 来说,IoSession 的close()方法被调用时才会毁掉这个方法。
*/
@Override
public void sessionClosed(IoSession session) throws Exception {
logger.info("服务端连接已经失效");
}
/**
* 这个方法在IoSession 的通道进入空闲状态时调用,对于UDP 协议来说,这个方法始终不会
* 被调用。
*/
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
logger.info("服务端进入空闲状态...");
}
/**
* 这个方法在你的程序、Mina 自身出现异常时回调,一般这里是关闭IoSession。
*/
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
logger.error("服务端发送异常...", cause);
}
}
客户端代码:
package org.demo;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.mina.common.ConnectFuture;
import org.apache.mina.common.IoConnector;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
/**
* @author wangmiao
* @version 创建时间:2012-4-24 下午10:57:53 简单说明
*/
public class HelloWorld2 extends Activity {
private static Logger logger = LoggerFactory.getLogger(HelloWorld2.class);
private static String HOST = "192.168.1.100";
private static int PORT = 8989;
private static String LOGIN_NAME = "";
public HelloWorld2() {
}
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println(1);
/*
* new Thread() { public void run() { socketServer(); } }.start();
*/
Button btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
EditText name = (EditText) findViewById(R.id.username);
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//name.setText("sysadmin"); 设置初始值
final Handler myHandler = new Handler(){
int i = 0;
@Override
public void handleMessage(Message msg) { //该线程位于主线程
// TODO Auto-generated method stub
//如果该消息是本程序所发送的
if(msg.what == 0x1233){
//主线程里面 显示操作
i++;
showToast("第"+i+"次连接开始....");
}
}
};
//定义一个计时器,让该计时器周期性的执行指定任务 TimerTask对象的本质就是启动一条新线程
new Timer().schedule(new TimerTask()
{
@Override
public void run() {
//新启动的线程无法访问该Activity里的组件
//所以需要通过Handler发送消息
// TODO Auto-generated method stub
Message msg = new Message();
msg.what = 0x1233;
//发送消息
myHandler.sendMessage(msg);
LOGIN_NAME = name.getText().toString();
//在子线程里面发送请求
socketServer();
}
},0,10000);
//
/*// 压力测试 10s秒钟 执行一次
while(true){
new Thread(){
public void run(){
socketServer();
}
}.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
}
});
System.out.println(1000);
}
public void showToast(final String text) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), text,
Toast.LENGTH_SHORT).show();
}
});
}
public void socketServer() {
// 创建一个非阻塞的客户端程序
System.out.println(2);
IoConnector connector = new NioSocketConnector();
// 设置链接超时时间
System.out.println(3);
connector.setConnectTimeout(5);
System.out.println(4);
// 添加过滤器
connector.getFilterChain().addLast(
"codec",
new ProtocolCodecFilter(new TextLineCodecFactory(Charset
.forName("UTF-8"), LineDelimiter.WINDOWS.getValue(),
LineDelimiter.WINDOWS.getValue())));
// 添加业务逻辑处理器类
connector.setHandler(new Demo1ClientHandler());
IoSession session = null;
try {
System.out.println(5);
System.out.println(HOST + "|" + PORT);
// 这里是异步操作 连接后立即返回
ConnectFuture future = connector.connect(new InetSocketAddress(
HOST, PORT));// 创建连接
System.out.println(6);
future.awaitUninterruptibly();// 等待连接创建完成
System.out.println(7);
session = future.getSession();// 获得session
// session.setAttribute(arg0, arg1)
String jsonStr = "{\"people\":["
+ "{ \"firstName\": \"问你t\", \"lastName\":\"McLaughlin\",\"email\": \"aaaa\" } ,"
+ "{ \"firstName\": \"Brett\", \"lastName\":\"McLaughlin\",\"email\": \"aaaa\" } ,] } ";
JSONObject json = createJSONObject();
// 根据key返回一个字符串
// //String username = json.getString("username");
// System.out.println("username==>"+username);
System.out.println(8);
session.write(json);// 发送消息
System.out.println(9);
session.getCloseFuture().awaitUninterruptibly();// 等待连接断开
connector.dispose();
System.out.println(Demo1ClientHandler.ini);
showToast(Demo1ClientHandler.ini);
} catch (Exception e) {
showToast("客户端链接异常,请检查网络");
logger.error("客户端链接异常...", e);
}
}
public static JSONObject createJSONObject() {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("username", LOGIN_NAME);
jsonObject.put("sex", "男");
jsonObject.put("QQ", "413425430");
jsonObject.put("Min.score", new Integer(99));
jsonObject.put("nickname", "梦中心境");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObject;
}
}
wangmiao 写道
这里客户端运用了 Handler消息的传递机制,主要是为了解决android应用的多线程问题--Android平台不允许Activity新启动的线程访问该Activity里的界面组件,这样就会导致新启动的线程无法改变界面组件的属性值。
Handler类的主要作用有两个:1.新启动的线程中发送消息 2.在线程中获取、处理消息
具体的关于Handler类的的使用去看相关的帮助说明。
逻辑处理:
package org.demo;
import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Demo1ClientHandler extends IoHandlerAdapter {
private static Logger logger = LoggerFactory
.getLogger(Demo1ClientHandler.class);
static String ini = "";
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
System.out.println(message);
System.out.println(11);
String msg = message.toString();
String info = "";
if ("1".equals(msg)) {
// session.close(); //用户登录成功 关闭连接
info = "登录成功";
} else {
info = "登录失败";
}
ini = info;
session.setAttribute("state", info);
session.close();
System.out.println(12);
// final HelloWorld h = new HelloWorld();
// h.DisplayToast(info);
logger.info("客户端接收到的信息为:" + msg);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
logger.error("客户端发生异常...", cause);
}
@Override
public void sessionCreated(IoSession arg0) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {
// TODO Auto-generated method stub
}
/**
* 这个方法在连接被打开时调用,它总是在sessionCreated()方法之后被调用。对于TCP 来
* 说,它是在连接被建立之后调用,你可以在这里执行一些认证操作、发送数据等。
*/
@Override
public void sessionOpened(IoSession arg0) throws Exception {
logger.info("ok", "i am ready!");
System.out.println(6);
}
}
- 大小: 22 KB
- 大小: 23.1 KB
- 大小: 21.2 KB
分享到:
相关推荐
MINA框架在Android开发中的应用,可以极大地简化网络通信的实现,尤其是对于需要处理大量并发连接和数据传输的场景。 首先,我们需要理解如何在Android Studio中集成MINA框架。这通常涉及将MINA的JAR库或AAR包导入...
通过以上步骤,你将能够掌握MINA框架在Android应用中的实际运用,解决可能出现的常见问题,从而构建出稳定、高效的网络通信功能。不过,实际开发中还可能遇到更多复杂情况,需要不断学习和实践,才能更好地应对挑战...
总结,Android Mina框架是实现高效、可靠的网络通信的重要工具。通过理解和掌握其原理及应用,开发者能更好地应对Android环境下的网络挑战,为用户打造更加流畅的应用体验。通过`MinaClientDemo`项目,开发者可以...
`Android-MinaSocket` 是一个针对Android平台的长连接库,它基于Apache Mina框架,提供了稳定且高效的网络通信能力。 Apache Mina(Model-View-Controller for Network Applications)是一个高度可扩展和灵活的网络...
通过这个Mina框架的示例,开发者可以更好地理解如何在Android平台上利用Mina进行网络编程,尤其是在需要高效、稳定长连接的场景下。同时,自定义编解码器的使用也能帮助开发者实现更灵活的数据交换格式,适应多样化...
在Android开发中,Socket编程是...总之,MINA框架为Android开发者提供了一个强大且灵活的工具,用于构建高效、可扩展的网络应用。掌握MINA的使用,不仅可以提高开发效率,还能让你的应用具备更高级别的网络通信功能。
在Android上使用Mina框架,可以极大地简化TCP通信的实现过程。TCP是一种面向连接的、可靠的传输层协议,适用于需要稳定数据传输的应用场景。Mina提供了一种事件驱动的模型,允许开发者通过异步方式处理网络I/O操作,...
在Android客户端与服务器端通信中,Mina框架因其高效的异步I/O处理能力,常被用来构建长连接,实现稳定且低延迟的数据传输。 长连接是指在通信过程中,一旦建立起连接,就保持该连接不关闭,直到通信结束或出现异常...
总的来说,通过学习和应用mina框架,开发者可以在Android平台上构建出高效、可靠的网络通信应用,从而实现智能家居设备之间的无缝连接和交互。这个例子不仅提供了一个学习mina的好起点,也展示了如何将理论知识转化...
**Android使用Mina与服务器通信Demo** Mina(Minimum Asynchronous Network)是一个高度可扩展的、高性能的网络应用开发框架,常用于构建基于TCP和UDP的网络应用,如服务器和客户端。在Android平台上,Mina可以帮助...
总的来说,MINA框架为Android和Java后台之间的通信提供了一种强大且高效的解决方案。结合提供的jar包和参考资料,开发者可以构建出稳定且高性能的消息推送系统。但要注意,由于MINA主要设计为服务器端框架,因此在...
根目录下的《Mina2.0学习笔记》应该包含了详细的教程和示例,涵盖了Mina的基本概念、配置、过滤器使用、协议处理等方面,是学习和理解Mina框架的重要参考资料。 总之,Android Java Socket框架Mina2.0提供了一个...
如果是一个源码项目,开发者可以通过阅读和修改代码来学习MinaServer的实现原理,理解如何在Android环境中配置和使用Apache Mina框架。如果是APK文件,用户可以直接安装到兼容的Android设备上运行和测试MinaServer...
Mina框架是一款强大的网络通信框架,广泛应用于Java和Android平台,尤其在实现高性能、高并发的长连接服务中表现出色。它提供了丰富的API和事件驱动模型,使得开发者可以方便地构建网络应用,如TCP、UDP服务器和...
1. **MINA框架基础**:MINA是一个基于NIO(Non-blocking I/O)的框架,它提供了一种处理大量并发连接的方式,通过非阻塞I/O模型,能够有效地利用系统资源,提高服务端的并发处理能力。MINA的核心组件包括Acceptor...
总之,这个“udp.rar”资源包是一个学习MINA框架在Android上实现UDP通信的好材料。它可以帮助开发者理解MINA框架的核心原理,掌握如何在Android环境中构建高效、可靠的UDP网络服务。通过深入研究提供的代码,你可以...
在Android开发中,Mina框架是一个非常重要的网络通信库,尤其适用于构建高性能、低延迟的网络应用程序。Mina源于Java平台,但通过一些适配,它也可以被集成到Android项目中,提供了一种灵活且强大的方式来处理网络...
MINA框架简介 MINA框架是Apache开发的一个网络通信应用框架,主要用于对基于TCP/IP、UDP/IP协议栈的通信框架。MINA框架可以帮助开发者快速...3. 数据推送应用:MINA框架可以用于开发数据推送应用,如Android数据推送。
在Android开发中,Mina库是一个非常强大的网络通信框架,它允许开发者构建高性能、高效率的网络应用程序。本文将深入探讨如何使用Mina库在Android客户端与Java服务器之间实现UDP(用户数据报协议)的数据交互。 UDP...
这个框架协议自己定义(即:底层已有字符串传输或Object传输,自己可以定义字符串会对象进行解析来制定自己的协议) 语音、图片等其实也是上传文件服务器再连个即时通信字符串通信而已; 注意:SSH-lib里有注意...