/** * 服務器端 * 啓動方式: startService(new Intent(this, MySocketService.class)); * */ public class MySocketService extends Service { private static final String TAG = "MySocketService"; private static final int PORT = 8000;//設置端口 private ExecutorService mExecutorService=null;//線程池 private ServerSocket server=null;//erverSocket負責接收客戶連接請求 private static MySocketService instance; //PrintWriter是用來操作Unicode, 一般需要處理中文時用PrintWriter好了 private List<PrintWriter> mWriters=new ArrayList<>(); private MsgCallBack mCallBack; private String mMsg; public static MySocketService getInstance(){ if(instance==null){ instance=new MySocketService(); } return instance; } @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Override public void onCreate() { super.onCreate(); instance=this; Log.d(TAG, "socket服務啓動" +GetIpAddress.getIP()); init(); } public void init(){ new Thread(mInitRun).start(); } /** * 開啓服務 * 建立連接 * */ private Runnable mInitRun = new Runnable() { @Override public void run () { try { //創建一個ServerSocket類,同時在運行該語句的計算機的指定端口建立一個監聽服務。 server = new ServerSocket(PORT); mExecutorService = Executors.newCachedThreadPool();//創建線程池 Log.e(TAG, "服務器已啓動..."); /** * 當Client程序需要從Server端獲取信息及其他服務時,應創建一個Socket對象: * Socket MySocket = new Socket("ServerComputerName",600); * 兩個參數,第一個是欲連接到的Server計算機的主機地址, * 第二個參數是該Server機上提供服務的端口號。 * * Socket對象建立成功後,就可以在Client和Server之間建立一個連接, * 並通過這個連接在兩個端口號之間傳遞數據。 * * 簡單來說,ServerSocket一般用於設置端口號和監聽, * 真正進行通信的是服務器端的Socket和客戶端的Socket, * 在ServerSocket進行accept後,就將主動權轉讓了。 * * */ Socket client = null; while (true) { client = server.accept(); Log.e(TAG, "客戶端已連接..."); PrintWriter writer = new PrintWriter( new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true); mWriters.add(writer); mExecutorService.execute(new ClientService(client, writer)); //start a new thread to handle the connection } } catch (Exception e) { Log.e("ServerService", "===錯誤信息:" + e.getMessage()); e.printStackTrace(); } } }; /** * 遍歷客戶端集合,給每一個客戶端發信息 * */ public void sendmsg(String msg){ mMsg=msg; int num =mWriters.size(); Log.d(TAG, "sendmsg: 發送信息"+msg+" "+num); for(int index=0;index<num;index++){ PrintWriter pout=mWriters.get(index); new Thread(new SendMsgRun(pout)).start(); } } /** * 發送信息的類 * 需要在線程裏進行 * */ class SendMsgRun implements Runnable{ PrintWriter mPrintWriter; public SendMsgRun(PrintWriter printWriter){ mPrintWriter=printWriter; } @Override public void run() { try{ mPrintWriter.println(mMsg); }catch (Exception e){ e.printStackTrace(); } } } class ClientService implements Runnable{ private Socket socket; private BufferedReader in=null; private String msg = ""; private PrintWriter mWriter; public ClientService(Socket socket,PrintWriter printWriter){ this.socket=socket; mWriter=printWriter; try{ in=new BufferedReader(new InputStreamReader(socket.getInputStream())); //客戶端只要一連到服務器,便向客戶端發送下面的信息。 msg = "服務器地址:" + this.socket.getInetAddress() + "come toal:" + mWriters.size() + "(服務器發送)"; sendmsg(msg); }catch (IOException e){ e.printStackTrace(); } } @Override public void run() { try { while (true) { if ((msg = in.readLine()) != null) { //當客戶端發送的信息爲:exit時,關閉連接 if (msg.equals("exit")) { System.out.println("ssssssss"); // mList.remove(socket); mWriters.remove(mWriter); in.close(); msg = "user:" + socket.getInetAddress() + "exit total:" + mWriters.size(); socket.close(); sendmsg(msg); break; //接收客戶端發過來的信息msg,然後發送給客戶端。 } else { // msg = socket.getInetAddress() + ":" + msg + "(服務器發送)"; // if ("startMusic".equals(msg)) { // sendmsg("playMusic"); // } if (mCallBack != null) { mCallBack.receive(msg); } //sendmsg(msg); } } } } catch (Exception e) { e.printStackTrace(); } } } public void setCallBack(MsgCallBack callBack) { this.mCallBack = callBack; } public void cleanClient () { // mList.clear(); mWriters.clear(); } }
【android學習記錄】socket 連接兩個android設備 服務器端
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.