近期因项目需要用到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>