Android socket与服务器通信长连接通信

    近期因项目需要用到Socket通信,实现客户端Socket 与 服务器通信。实现客户端发送信息--》服务器接收信息---》服务器返回信息--》客户端接收返回信息的长连接通讯,已测试通过。

    服务端代码:

    

package com.cj.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server extends Thread{
	private ServerSocket serverSocket = null;
	private int port = 8142;

	@Override
	public void run() {
		try {
			serverSocket = new ServerSocket(port);
			System.out.println("server builded.....");
			OutputStream out = null;
			InputStream in = null;
			while(true){
				Socket socket = serverSocket.accept();
				try{
					in = socket.getInputStream();
					out = socket.getOutputStream();
					while(true){
						String reciverData = readFromInputStream(in);
                        System.out.println(reciverData);
                        reciverData = "已接收--》\n" + reciverData;
                        writeToClient(out, reciverData);                        
					}
				}catch(Exception e){
					e.printStackTrace();
				}finally{
					in.close();
					out.close();
				}
//				BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//				PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
//				String a = null;
//				String b= null;
//				while((a = in.readLine()) != null){
//					b += a;
//					System.out.println(a);
//					out.println("已接收。。。。。" + a);
//					out.flush();                     
//				}
				
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				serverSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			};
		}
	}
	
	public String readFromInputStream(InputStream in){
		int count = 0;
		byte[] inDatas = null;
		try{
			while(count == 0){
				count = in.available();
			}
			inDatas = new byte[count];
			in.read(inDatas);
			return new String(inDatas);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	public void writeToClient(OutputStream out, String data){
		try{
			out.write(data.getBytes());
			out.flush();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}


package com.cj.socket;

public class Test {
    public static void main(String[] argv){
    	new Server().start();
    }
}

    客户端代码:

package com.cj.testsocket.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;

import android.util.Log;

public class ClientSocket extends Thread{
	public static final String SOCKET_TAG = "socketTag";
	public static final long HEART_TIME = 10000;
	public static final long SEND_TIME = 1000;
	private static final String HEART_MSG = "heart"; 
	/**
	 * 接收线程
	 */
	private Thread mReciverThread = null;

	/**
	 * 心跳时间
	 */
	private long mHeartTime = 0;

	/**
	 * client socket
	 */
	private Socket mSocket = null;                  

	private InputStream in = null;

	private OutputStream  out = null;

	/**
	 * 主机IP地址
	 */
	private String serverUrl = null;

	/**
	 * 主机端口
	 */
	private int serverPort = 0;

	/**
	 * 消息队列
	 */
	private volatile List<String> mMsgQueue = null;

	/**
	 * 接收到服务端返回信息回调接口
	 */
	private OnSocketRecieveCallBack mOnSocketRecieveCallBack;

	/*********************************************
	 * 
	 * gettter or setter
	 * 
	 ********************************************/
	public Socket getSocket() {
		return mSocket;
	}

	public String getServerUrl() {
		return serverUrl;
	}

	public void setServerUrl(String serverUrl) {
		this.serverUrl = serverUrl;
	}

	public int getServerPort() {
		return serverPort;
	}

	public void setServerPort(int serverPort) {
		this.serverPort = serverPort;
	}

	public List<String> getMsgQueue() {
		return mMsgQueue;
	}

	public void setMsgQueue(List<String> mMsgQueue) {
		this.mMsgQueue = mMsgQueue;
	}

	public OnSocketRecieveCallBack getOnSocketRecieveCallBack() {
		return mOnSocketRecieveCallBack;
	}

	public void setOnSocketRecieveCallBack(OnSocketRecieveCallBack mOnSocketRecieveCallBack) {
		this.mOnSocketRecieveCallBack = mOnSocketRecieveCallBack;
	}	

	/**
	 * 构造函数
	 */
	public ClientSocket(String hostName, int port){
		serverUrl = hostName;
		serverPort = port;
		mMsgQueue = new LinkedList<String>();

		mReciverThread = new Thread(){
			@Override
			public void run(){
				while(!this.isInterrupted()){
					reciverMsgFromServer();
				}
			}
		};
		mReciverThread.start();
	}

	/***********************************************
	 * 
	 * Methods
	 * 
	 **********************************************/
	public String readFromInputStream(InputStream in){
		int count = 0;
		byte[] inDatas = null;
		try{
			while(count == 0){
				count = in.available();
			}
			inDatas = new byte[count];
			in.read(inDatas);
			return new String(inDatas);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	private void reciverMsgFromServer(){
		// 接收数据
		if(mSocket != null && mSocket.isConnected() && !mSocket.isInputShutdown() && in != null){
			try {
				String recieveMsg = readFromInputStream(in);
				if(mOnSocketRecieveCallBack != null)
					mOnSocketRecieveCallBack.OnRecieveFromServerMsg(recieveMsg);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 发送心跳包 
	 */
	public void sendHeart(String msgHeart){
		((LinkedList<String>)mMsgQueue).addFirst(msgHeart);
	}

	/**
	 * socket 是否有断开连接
	 * @return
	 */
	public boolean isSocketConnected(){
		if(mSocket != null && mSocket.isConnected()) return true; 
		return false;
	}
	/**
	 * 添加发送消息到队列
	 * @param msg
	 */
	public void addSendMsgToQueue(String msg){
		mMsgQueue.add(msg);
	}

	/**
	 * 判断消息队列是否为空
	 * @return
	 */
	public boolean isMsgQueueEmpty(){
		return mMsgQueue.isEmpty();
	}

	@Override
	public void run() {
		InetAddress inetAddress = null;
		try {
			mSocket = new Socket(InetAddress.getByName(serverUrl), serverPort);
			in = mSocket.getInputStream();
			out = mSocket.getOutputStream();
			mHeartTime = System.currentTimeMillis();
			Log.v(SOCKET_TAG, "client socket create successed");
			// 轮询发送消息列表中的数据
			while(true){
				// 判断是否要发送心跳包
				if(Math.abs(mHeartTime - System.currentTimeMillis()) > HEART_TIME) sendHeart(HEART_MSG);

				Thread.sleep(SEND_TIME);
				// 判断client socket 是否连接上Server
				if(mSocket.isConnected()){
					Log.v(SOCKET_TAG, "### client socket connected ###");
					// 发送数据
					if(!mSocket.isOutputShutdown() && !isMsgQueueEmpty()){
						out.write(mMsgQueue.get(0).getBytes());
						Log.v(SOCKET_TAG, "sned msg toServer: " + mMsgQueue.get(0));
						Log.v(SOCKET_TAG, "## msg count : " + mMsgQueue.size());
						// 将发送过的数据移除消息列表
						mMsgQueue.remove(0);
						mHeartTime = System.currentTimeMillis();
					}
				}else{
					// 重建连接
					Log.v(SOCKET_TAG, "client socket disconnected");
					if(!mSocket.isClosed()) mSocket.close();
					inetAddress = InetAddress.getByName(serverUrl);
					mSocket = new Socket(inetAddress, serverPort);
				}
			}
		}catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Log.v(SOCKET_TAG,e.getMessage());
		} catch (UnknownHostException e) {
			e.printStackTrace();
			Log.v(SOCKET_TAG,e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			Log.v(SOCKET_TAG,e.getMessage());
		}finally{
			if(out != null)
				try {
					out.close();
				} catch (IOException e2) {
					// TODO Auto-generated catch block
					e2.printStackTrace();
				}
			if(in != null){
				try {
					in.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}

			if(mSocket != null){
				try {
					mSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
					Log.v(SOCKET_TAG,e.getMessage());
				}
			}
			Log.v(SOCKET_TAG, "client socket close");
		}
	}

	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		if(mReciverThread != null && !mReciverThread.isInterrupted()){
			mReciverThread.interrupt();
			mReciverThread = null;
		}

		if(mSocket != null && !mSocket.isClosed()){
			mSocket.close();
		}
		Log.v(SOCKET_TAG, "client socket destory");
	}

	/**
	 * 接收到服务端返回信息回调接口
	 * @author Administrator
	 *
	 */
	public interface OnSocketRecieveCallBack{
		public void OnRecieveFromServerMsg(String msg);
	}
}



package com.cj.testsocket;

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

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.cj.testsocket.socket.ClientSocket;
import com.cj.testsocket.socket.ClientSocket.OnSocketRecieveCallBack;

public class MainActivity extends Activity implements OnClickListener, OnSocketRecieveCallBack{
	public static final String SERVER_NAME = "192.168.0.119";
	public static final int PORT = 8142;
	
	Button btn_send;
	EditText ed_send;
	ListView mListView;
	ArrayAdapter<String> arryAdapter = null;
	List<String> mDatas = null;
	Handler mHandler = new Handler(){

		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			mDatas.add((String)msg.obj);
			arryAdapter.notifyDataSetChanged();
		}

	};
	ClientSocket mClientSocket = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mDatas = new ArrayList<String>();
		mDatas.add("Hello world");
		arryAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mDatas);

		ed_send = (EditText)this.findViewById(R.id.et_send);
		btn_send = (Button)this.findViewById(R.id.btn_send);
		btn_send.setOnClickListener(this);
		mListView = (ListView)this.findViewById(R.id.list);
		mListView.setAdapter(arryAdapter);

		mClientSocket = new ClientSocket(SERVER_NAME, PORT);
		mClientSocket.setOnSocketRecieveCallBack(this);
		mClientSocket.start();
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		String msg = ed_send.getText().toString();

		if(msg != null && mClientSocket.isSocketConnected()){
			mClientSocket.addSendMsgToQueue(msg);
			mDatas.add(msg);
			arryAdapter.notifyDataSetChanged();
			ed_send.setText("");
		}
	}

	@Override
	public void OnRecieveFromServerMsg(String msg) {
		// TODO Auto-generated method stub
		if(msg != null){
			Message message = Message.obtain();
			message.obj = msg;
			mHandler.sendMessage(message);
		}

	}
}

    布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:listSelector="@android:color/transparent"
        android:transcriptMode="alwaysScroll"
        android:stackFromBottom="true"/>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="48dp"
        android:layout_alignParentBottom="true"
        android:background="#818080"
        android:orientation="horizontal" >

        <EditText
            android:id="@+id/et_send"
            android:background="#ffffff"
            android:layout_margin="4dp"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="5" 
            android:hint="请输入要发送的信息"/>

        <Button
            android:id="@+id/btn_send"
            android:background="@drawable/btn_send_selector"
            android:layout_margin="4dp"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="2"
            android:text="发  送" />
    </LinearLayout>

</RelativeLayout>


AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cj.testsocket"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.cj.testsocket.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值