標籤:
在實際的應用中用戶端可能需要和伺服器端保持長時間的通訊,即伺服器需要不斷地讀取用戶端資料,並向用戶端寫入資料;用戶端也需要不斷地讀取伺服器資料,並向伺服器寫入資料。
簡單實現代碼如下:
1 public class MyServer { 2 //定義儲存所有Socket的ArrayList 3 public staticArrayList socketList = newArrayList(); 4 5 public static voidmain(String[] args) throws IOException { 6 // TODOAuto-generated method stub 7 ServerSocket ss = newServerSocket(30000); 8 while(true){ 9 //此代碼會阻塞,將一直等待別人串連10 Socket s = ss.accept();11 socketList.add(s);12 //每當用戶端串連後啟動一條ServerThread線程為該用戶端服務13 new Thread(newServerThread(s)).start();14 }15 }16 }17 服務端通訊線程18 public classServerThread implements Runnable {19 //定義當前線程所處理的Socket20 Socket s = null;21 //該線程所處理的Socket所對應的輸入資料流22 BufferedReader br = null;23 public ServerThread(Socket s) throws IOException {24 this.s = s;25 //初始化該Socket對應的輸入資料流26 br = newBufferedReader(new InputStreamReader(s.getInputStream(),27 "utf-8"));28 }29 @Override30 public void run() {31 // TODOAuto-generated method stub32 try33 {34 String content = null;35 //採用迴圈不斷從Socket中讀取用戶端發送過來的資料36 while((content = readFromClient())!=null){37 //遍曆socketList中的每個Socket38 //將讀到的內容向每個Socket發送一次39 for(Socket s : MyServer.socketList){40 OutputStream os = s.getOutputStream();41 os.write((content + "\n").getBytes("utf-8"));//注意發送訊息的時候一定要加分行符號,因為在readLine的時候看的就是分行符號42 }43 }44 }catch(IOException e) {45 e.printStackTrace();46 }47 }48 49 public String readFromClient()50 {51 try{52 return br.readLine();53 }catch(IOException e){ //如果捕捉到異常,表明該Socket對應的用戶端已經被關閉54 //刪除該Socket55 MyServer.socketList.remove(s);56 }57 return null;58 }59 }
public classMainActivity extends Activity { EditText input, show; Button send; OutputStream os; Handler handler; @Override protected voidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); input = (EditText) findViewById(R.id.input); send = (Button) findViewById(R.id.send); show = (EditText) findViewById(R.id.show); handler = new Handler() { public voidhandleMessage(android.os.Message msg) { if (msg.what == 0x123) { show.append("\n" + msg.obj.toString()); } }; }; newAsyncTask(){ @Override protected String doInBackground(String... params) { // TODOAuto-generated method stub Socket s; try { s = new Socket("192.168.1.75", 30000); //用戶端啟動ClientThread線程,不斷讀取來自伺服器的資料 new Thread(newClientThread(s, handler)).start(); os = s.getOutputStream(); } catch(Exception e) { e.printStackTrace(); } return null; } }.execute(""); send.setOnClickListener(newOnClickListener() { @Override public voidonClick(View v) { // TODOAuto-generated method stub try { //將使用者在文字框中輸入的內容寫入網路 os.write((input.getText().toString() + "\r\n") .getBytes("utf-8")); input.setText(""); } catch(IOException e) { // TODOAuto-generated catch block e.printStackTrace(); } } }); }}用戶端通訊線程public classClientThread implements Runnable { private Socket s; //該線程負責處理的Socket private Handler handler; //該線程所處理的Socket對應的輸入資料流 BufferedReader br = null; public ClientThread(Socket s, Handler handler) throws IOException { this.s = s; this.handler = handler; br = newBufferedReader(new InputStreamReader(s.getInputStream())); } @Override public void run() { // TODOAuto-generated method stub try { String content = null; //不斷讀取Socket輸入資料流中的內容 while ((content = br.readLine()) != null) { //每當讀到來自伺服器的資料後,發送訊息通知程式介面顯示資料 Message msg = newMessage(); msg.what = 0x123; msg.obj = content; handler.sendMessage(msg); } } catch(Exception e) { e.printStackTrace(); } }}
原文地址:http://i.cnblogs.com/EditPosts.aspx?opt=1
參考地址:
android中對服務端的長串連【socket】
http://blog.csdn.net/yaya_soft/article/details/11778593
http://gavinwen.me/?post=2
http://www.cnblogs.com/asi24/archive/2013/06/05/3119444.html
http://coach.iteye.com/blog/2024444
http://gstarwd.iteye.com/blog/619171
Android學習筆記(七)之Android socket通訊-解決中文亂碼
http://www.2cto.com/kf/201209/155337.html
Android網路編程Socket長串連