最近在实现socket通信,所以写个demo来简单实现下。我用了一种是原始的socket实现,另一种是MINA框架来实现的。
下载demo:http://download.csdn.net/detail/qq_29774291/9826648
一.先看第一种方法
a)、创建Socket对象,指明需要连接的服务器的地址和端口。
b)、建立连接后,通过输出流向服务器发送请求信息。
c)、通过输入流获取服务器的响应信息。
d)、关闭响应资源
如下是主要代码
package com.item.item.sock.socket;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.SystemClock;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.InetSocketAddress;import java.net.Socket;import java.net.SocketAddress;/**
* Socket 通信 */public class MyServiceOne extends Service { private Socket socket; private BufferedReader in = null; private BufferedWriter out = null; private boolean close = true; private Thread readThread;
@Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override public void onCreate() { super.onCreate();
close = true; new Thread(new Runnable() {
@Override public void run() { int count = 0; for(;;){ try {
count++;
SocketAddress socketAddress = new InetSocketAddress(ConnectUtils.HOST,ConnectUtils.POST);
socket = new Socket();
socket.connect(socketAddress,10000); if(socket.isConnected()){
System.out.println("socket 连接成功");
in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
out =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8")); //发送一个消息
out.write("start");
out.flush(); //开启一个线程来读取服务器发来的消息 readThread.start(); break;
}
}catch (Exception e){ if(count > ConnectUtils.IDLE_TIME){ break;
}else {
SystemClock.sleep(5000);
}
}
}
}
}).start();
readThread = new Thread(new Runnable() {
@Override public void run() { while (close){
String readtext = readText(socket); if(readtext !=null){
System.out.println("服务器发来的消息:" + readtext);
}
}
}
});
} private String readText(Socket socket) {
String string = null; if(socket.isConnected()){ try { char[] buffer = new char[8000]; int count = 0; if((count = in.read(buffer)) > 0){ char[] temp = new char[count]; for(int i=0;i
temp[i] = buffer[i];
}
string = new String(temp);
}
}catch (Exception e){
string = null;
}
} return string;
}
@Override public void onDestroy() { super.onDestroy();
close = false; if(socket != null){ try {
socket.close();
socket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二.第二种方法是用MINA框架实现的
package com.item.item.sock.socket;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.SystemClock;import android.util.Log;import org.apache.mina.core.future.ConnectFuture;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.service.IoService;import org.apache.mina.core.service.IoServiceListener;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.filter.codec.textline.TextLineCodecFactory;import org.apache.mina.transport.socket.nio.NioSocketConnector;import java.net.InetSocketAddress;import java.nio.charset.Charset;/**
* 使用MINA框架实现socket通信
* 由于接受消息会阻塞Android线程,所以开在子线程中(同时将其放在Service中,让其在后台运行) */public class MyServiceTwo extends Service { private String TAG = "jiejie"; private IoSession session = null; private MinaClientHandler minaClientHandler; private NioSocketConnector connector = null;
@Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override public void onCreate() { super.onCreate();
minaClientHandler = new MinaClientHandler(); new Thread(new Runnable() {
@Override public void run() { //创建连接客户端
connector = new NioSocketConnector(); //设置连接超时时间
connector.setConnectTimeoutMillis(30000); //添加过滤器
connector.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); //设置接收缓冲区大小
connector.getSessionConfig().setReadBufferSize(1024); //设置处理器 connector.setHandler(minaClientHandler); //设置默认方位地址
connector.setDefaultRemoteAddress(new InetSocketAddress(ConnectUtils.HOST,ConnectUtils.POST)); //添加重连监听
connector.addListener(new IoListener(){
@Override public void sessionDestroyed(IoSession ioSession) throws Exception { int count = 0; for(;;){ try {
count++;
ConnectFuture future = connector.connect();
future.awaitUninterruptibly();//等待连接创建完成
session = future.getSession();//获取session
if(session.isConnected()){
System.out.println("断线了 但是又重连了");
count = 0; break;
}
}catch (Exception e){ if(count > ConnectUtils.IDLE_TIME){ break;
}else {
SystemClock.sleep(5000);
}
}
}
}
}); for(;;){ try {
ConnectFuture future = connector.connect();
future.awaitUninterruptibly();
System.out.println("socket 连接成功");
session = future.getSession();
session.write("start"); break;
}catch (Exception e){
SystemClock.sleep(5000);
}
}
}
}).start();
}
@Override public void onDestroy() { super.onDestroy();
connector.dispose();
} private class MinaClientHandler extends IoHandlerAdapter{
@Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { super.exceptionCaught(session, cause);
Log.d(TAG,"exceptionCaught--------" + cause);
}
@Override public void messageReceived(IoSession session, Object message) throws Exception { super.messageReceived(session, message);
Log.d(TAG,"messageReceived---------" + message );
}
@Override public void messageSent(IoSession session, Object message) throws Exception { super.messageSent(session, message);
Log.d(TAG,"messageSent-------" + message);
}
@Override public void sessionClosed(IoSession session) throws Exception { super.sessionClosed(session);
Log.d(TAG,"sessionClosed-------");
}
@Override public void sessionCreated(IoSession session) throws Exception { super.sessionCreated(session);
Log.d(TAG,"sessionCreated------" + session);
}
@Override public void sessionOpened(IoSession session) throws Exception { super.sessionOpened(session);
Log.d(TAG,"sessionOpened---------");
}
} /**
* 创建一个监听器实现mina的IoServiceListener接口,里面的方法可以不用实现 */
private class IoListener implements IoServiceListener{
@Override public void serviceActivated(IoService ioService) throws Exception {
}
@Override public void serviceIdle(IoService ioService, IdleStatus idleStatus) throws Exception {
}
@Override public void serviceDeactivated(IoService ioService) throws Exception {
}
@Override public void sessionCreated(IoSession ioSession) throws Exception {
}
@Override public void sessionClosed(IoSession ioSession) throws Exception {
}
@Override public void sessionDestroyed(IoSession ioSession) throws Exception {
}
}
}
三.对于粘包的处理 是建立临时缓冲区来处理
public synchronized void Decode(char[] data)
{ for (int i = 0; i < data.length; i++)
{ char byt = data[i]; this.temp.add(byt); if (byt == '"')
{ if (!this.instring)
{ this.instring = true;
} else if (getPrev() != '\\')
{ this.instring = false;
}
} if (instring) continue; if (byt == '}' || byt == ']')
{
end = true;
left--;
} if (byt == '{' || byt == '[')
{
left++;
} if ((left) < 0)
{
temp.clear(); this.instring = false; this.left = 0; continue;
} if (end && left == 0)
{
end = false; char[] p =new char[temp.size()]; // temp.toArray(p) ;//完整协议包
for(int j =0; j< temp.size();j++){
p[j] = temp.get(j);
}
// todo : log// if (OnPackageHanded != null) {// OnPackageHanded(package);// }
if(this.HandledPackage.size()>100){
this.HandledPackage.poll();
} this.HandledPackage.offer(p);
temp.clear(); this.instring = false; this.left = 0; continue;
}
}
}
网友评论