android之socket編程實例

注意點:註冊訪問的網絡權限;android中UI線程不能有訪問網絡的操作,否則會報android.os.NetworkOnMainThreadException的異常

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <uses-permission   
  2.     android:name="android.permission.INTERNET"/>  

      Android開發聯盟③ 433233634

實例一

客戶端


[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.android.xiong.simplesocket;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.io.OutputStream;  
  7. import java.net.InetSocketAddress;  
  8. import java.net.Socket;  
  9. import java.net.SocketTimeoutException;  
  10.   
  11. import android.app.Activity;  
  12. import android.os.Bundle;  
  13. import android.os.Handler;  
  14. import android.os.Message;  
  15. import android.view.Menu;  
  16. import android.view.View;  
  17. import android.view.View.OnClickListener;  
  18. import android.widget.Button;  
  19. import android.widget.EditText;  
  20. import android.widget.TextView;  
  21.   
  22. public class MainActivity extends Activity {  
  23.     Socket socket = null;  
  24.     String buffer = "";  
  25.     TextView txt1;  
  26.     Button send;  
  27.     EditText ed1;  
  28.     String geted1;  
  29.     public Handler myHandler = new Handler() {  
  30.         @Override  
  31.         public void handleMessage(Message msg) {  
  32.             if (msg.what == 0x11) {  
  33.                 Bundle bundle = msg.getData();  
  34.                 txt1.append("server:"+bundle.getString("msg")+"\n");  
  35.             }  
  36.         }  
  37.   
  38.     };  
  39.   
  40.     @Override  
  41.     protected void onCreate(Bundle savedInstanceState) {  
  42.         super.onCreate(savedInstanceState);  
  43.         setContentView(R.layout.activity_main);  
  44.         txt1 = (TextView) findViewById(R.id.txt1);  
  45.         send = (Button) findViewById(R.id.send);  
  46.         ed1 = (EditText) findViewById(R.id.ed1);  
  47.         send.setOnClickListener(new OnClickListener() {  
  48.   
  49.             @Override  
  50.             public void onClick(View v) {  
  51.                 geted1 = ed1.getText().toString();  
  52.                 txt1.append("client:"+geted1+"\n");  
  53.                 //啓動線程 向服務器發送和接收信息  
  54.                 new MyThread(geted1).start();  
  55.             }  
  56.         });  
  57.   
  58.     }  
  59.   
  60.     class MyThread extends Thread {  
  61.   
  62.         public String txt1;  
  63.   
  64.         public MyThread(String str) {  
  65.             txt1 = str;  
  66.         }  
  67.   
  68.         @Override  
  69.         public void run() {  
  70.             //定義消息  
  71.             Message msg = new Message();  
  72.             msg.what = 0x11;  
  73.             Bundle bundle = new Bundle();  
  74.             bundle.clear();  
  75.             try {  
  76.                 //連接服務器 並設置連接超時爲5秒  
  77.                 socket = new Socket();  
  78.                 socket.connect(new InetSocketAddress("1.1.9.30"30000), 5000);  
  79.                 //獲取輸入輸出流  
  80.                 OutputStream ou = socket.getOutputStream();  
  81.                 BufferedReader bff = new BufferedReader(new InputStreamReader(  
  82.                         socket.getInputStream()));  
  83.                 //讀取發來服務器信息  
  84.                 String line = null;  
  85.                 buffer="";  
  86.                 while ((line = bff.readLine()) != null) {  
  87.                     buffer = line + buffer;  
  88.                 }  
  89.                   
  90.                 //向服務器發送信息  
  91.                 ou.write("android 客戶端".getBytes("gbk"));  
  92.                 ou.flush();  
  93.                 bundle.putString("msg", buffer.toString());  
  94.                 msg.setData(bundle);  
  95.                 //發送消息 修改UI線程中的組件  
  96.                 myHandler.sendMessage(msg);  
  97.                 //關閉各種輸入輸出流  
  98.                 bff.close();  
  99.                 ou.close();  
  100.                 socket.close();  
  101.             } catch (SocketTimeoutException aa) {  
  102.                 //連接超時 在UI界面顯示消息  
  103.                 bundle.putString("msg""服務器連接失敗!請檢查網絡是否打開");  
  104.                 msg.setData(bundle);  
  105.                 //發送消息 修改UI線程中的組件  
  106.                 myHandler.sendMessage(msg);  
  107.             } catch (IOException e) {  
  108.                 e.printStackTrace();  
  109.             }  
  110.         }  
  111.     }  
  112.   
  113.     @Override  
  114.     public boolean onCreateOptionsMenu(Menu menu) {  
  115.         // Inflate the menu; this adds items to the action bar if it is present.  
  116.         getMenuInflater().inflate(R.menu.main, menu);  
  117.         return true;  
  118.     }  
  119.   
  120. }  

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:paddingBottom="@dimen/activity_vertical_margin"  
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  7.     android:paddingRight="@dimen/activity_horizontal_margin"  
  8.     android:paddingTop="@dimen/activity_vertical_margin"  
  9.     tools:context=".MainActivity" >  
  10.   
  11.     <EditText   
  12.         android:id="@+id/ed1"  
  13.         android:layout_width="match_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:hint="給服務器發送信息"/>  
  16.     <Button   
  17.         android:id="@+id/send"  
  18.         android:layout_width="match_parent"  
  19.         android:layout_height="wrap_content"  
  20.         android:layout_below="@id/ed1"  
  21.         android:text="發送"/>  
  22.     <TextView   
  23.         android:id="@+id/txt1"  
  24.         android:layout_width="match_parent"  
  25.         android:layout_height="wrap_content"  
  26.         android:layout_below="@id/send"/>  
  27.       
  28.       
  29.   
  30.   
  31. </RelativeLayout>  

服務端

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.android.net;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.ServerSocket;  
  5. import java.net.Socket;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. public class AndroidService {  
  10.   
  11.   
  12.     public static void main(String[] args) throws IOException {  
  13.         ServerSocket serivce = new ServerSocket(30000);  
  14.         while (true) {  
  15.             //等待客戶端連接  
  16.             Socket socket = serivce.accept();  
  17.             new Thread(new AndroidRunable(socket)).start();  
  18.         }  
  19.     }  
  20.   
  21. }  

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.android.net;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.BufferedWriter;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.io.InputStreamReader;  
  8. import java.io.OutputStream;  
  9. import java.io.OutputStreamWriter;  
  10. import java.io.PrintWriter;  
  11. import java.net.Socket;  
  12.   
  13. public class AndroidRunable implements Runnable {  
  14.   
  15.     Socket socket = null;  
  16.   
  17.     public AndroidRunable(Socket socket) {  
  18.         this.socket = socket;  
  19.     }  
  20.   
  21.     @Override  
  22.     public void run() {  
  23.         // 向android客戶端輸出hello worild  
  24.         String line = null;  
  25.         InputStream input;  
  26.         OutputStream output;  
  27.         String str = "hello world!";  
  28.         try {  
  29.             //向客戶端發送信息  
  30.             output = socket.getOutputStream();  
  31.             input = socket.getInputStream();  
  32.             BufferedReader bff = new BufferedReader(  
  33.                     new InputStreamReader(input));  
  34.             output.write(str.getBytes("gbk"));  
  35.             output.flush();  
  36.             //半關閉socket    
  37.             socket.shutdownOutput();  
  38.             //獲取客戶端的信息  
  39.             while ((line = bff.readLine()) != null) {  
  40.                 System.out.print(line);  
  41.             }  
  42.             //關閉輸入輸出流  
  43.             output.close();  
  44.             bff.close();  
  45.             input.close();  
  46.             socket.close();  
  47.   
  48.         } catch (IOException e) {  
  49.             e.printStackTrace();  
  50.         }  
  51.   
  52.     }  
  53. }  

實例二

客戶端

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.android.xiong.sockettwotest;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Message;  
  7. import android.view.Menu;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.widget.Button;  
  11. import android.widget.EditText;  
  12. import android.widget.TextView;  
  13.   
  14. public class MainActivity extends Activity {  
  15.   
  16.     // 定義界面上的兩個文本框  
  17.     EditText input;  
  18.     TextView show;  
  19.     // 定義界面上的一個按鈕  
  20.     Button send;  
  21.     Handler handler;  
  22.     // 定義與服務器通信的子線程  
  23.     ClientThread clientThread;  
  24.   
  25.     @Override  
  26.     protected void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         setContentView(R.layout.activity_main);  
  29.         input = (EditText) findViewById(R.id.input);  
  30.         show = (TextView) findViewById(R.id.show);  
  31.         send = (Button) findViewById(R.id.send);  
  32.         handler = new Handler() {  
  33.   
  34.             @Override  
  35.             public void handleMessage(Message msg) {  
  36.                 // 如果消息來自子線程  
  37.                 if (msg.what == 0x123) {  
  38.                     // 將讀取的內容追加顯示在文本框中  
  39.                     show.append("\n" + msg.obj.toString());  
  40.                 }  
  41.             }  
  42.         };  
  43.         clientThread = new ClientThread(handler);  
  44.         // 客戶端啓動ClientThread線程創建網絡連接、讀取來自服務器的數據  
  45.         new Thread(clientThread).start();  
  46.         send.setOnClickListener(new OnClickListener() {  
  47.   
  48.             @Override  
  49.             public void onClick(View v) {  
  50.                 try {  
  51.                     // 當用戶按下按鈕之後,將用戶輸入的數據封裝成Message  
  52.                     // 然後發送給子線程Handler  
  53.                     Message msg = new Message();  
  54.                     msg.what = 0x345;  
  55.                     msg.obj = input.getText().toString();  
  56.                     clientThread.revHandler.sendMessage(msg);  
  57.                     input.setText("");  
  58.   
  59.                 } catch (Exception e) {  
  60.   
  61.                 }  
  62.             }  
  63.         });  
  64.     }  
  65.   
  66.     @Override  
  67.     public boolean onCreateOptionsMenu(Menu menu) {  
  68.         getMenuInflater().inflate(R.menu.main, menu);  
  69.         return true;  
  70.     }  
  71.   
  72. }  

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.android.xiong.sockettwotest;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.io.OutputStream;  
  7. import java.net.InetSocketAddress;  
  8. import java.net.Socket;  
  9. import java.net.SocketTimeoutException;  
  10.   
  11. import android.os.Handler;  
  12. import android.os.Looper;  
  13. import android.os.Message;  
  14.   
  15. public class ClientThread implements Runnable {  
  16.     private Socket s;  
  17.     // 定義向UI線程發送消息的Handler對象  
  18.     Handler handler;  
  19.     // 定義接收UI線程的Handler對象  
  20.     Handler revHandler;  
  21.     // 該線程處理Socket所對用的輸入輸出流  
  22.     BufferedReader br = null;  
  23.     OutputStream os = null;  
  24.   
  25.     public ClientThread(Handler handler) {  
  26.         this.handler = handler;  
  27.     }  
  28.   
  29.     @Override  
  30.     public void run() {  
  31.         s = new Socket();  
  32.         try {  
  33.             s.connect(new InetSocketAddress("1.1.9.30"3000), 5000);  
  34.             br = new BufferedReader(new InputStreamReader(s.getInputStream()));  
  35.             os = s.getOutputStream();  
  36.             // 啓動一條子線程來讀取服務器相應的數據  
  37.             new Thread() {  
  38.   
  39.                 @Override  
  40.                 public void run() {  
  41.                     String content = null;  
  42.                     // 不斷的讀取Socket輸入流的內容  
  43.                     try {  
  44.                         while ((content = br.readLine()) != null) {  
  45.                             // 每當讀取到來自服務器的數據之後,發送的消息通知程序  
  46.                             // 界面顯示該數據  
  47.                             Message msg = new Message();  
  48.                             msg.what = 0x123;  
  49.                             msg.obj = content;  
  50.                             handler.sendMessage(msg);  
  51.                         }  
  52.                     } catch (IOException io) {  
  53.                         io.printStackTrace();  
  54.                     }  
  55.                 }  
  56.   
  57.             }.start();  
  58.             // 爲當前線程初始化Looper  
  59.             Looper.prepare();  
  60.             // 創建revHandler對象  
  61.             revHandler = new Handler() {  
  62.   
  63.                 @Override  
  64.                 public void handleMessage(Message msg) {  
  65.                     // 接收到UI線程的中用戶輸入的數據  
  66.                     if (msg.what == 0x345) {  
  67.                         // 將用戶在文本框輸入的內容寫入網絡  
  68.                         try {  
  69.                             os.write((msg.obj.toString() + "\r\n")  
  70.                                     .getBytes("gbk"));  
  71.                         } catch (Exception e) {  
  72.                             e.printStackTrace();  
  73.                         }  
  74.                     }  
  75.                 }  
  76.   
  77.             };   
  78.             // 啓動Looper  
  79.             Looper.loop();  
  80.   
  81.         } catch (SocketTimeoutException e) {  
  82.             Message msg = new Message();  
  83.             msg.what = 0x123;  
  84.             msg.obj = "網絡連接超時!";  
  85.             handler.sendMessage(msg);  
  86.         } catch (IOException io) {  
  87.             io.printStackTrace();  
  88.         }  
  89.   
  90.     }  
  91. }  

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:paddingBottom="@dimen/activity_vertical_margin"  
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  7.     android:paddingRight="@dimen/activity_horizontal_margin"  
  8.     android:paddingTop="@dimen/activity_vertical_margin"  
  9.     tools:context=".MainActivity" >  
  10.   
  11.     <EditText  
  12.         android:id="@+id/input"  
  13.         android:layout_width="match_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:hint="@string/input" />  
  16.     <Button   
  17.         android:id="@+id/send"  
  18.         android:layout_width="match_parent"  
  19.         android:layout_height="wrap_content"  
  20.         android:text="@string/send"  
  21.         android:layout_below="@id/input"/>  
  22.     <TextView   
  23.         android:id="@+id/show"  
  24.         android:layout_width="match_parent"  
  25.         android:layout_height="wrap_content"  
  26.         android:layout_below="@id/send"/>  
  27.   
  28. </RelativeLayout>  

服務端


[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.android.net;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.ServerSocket;  
  5. import java.net.Socket;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. public class MyService {  
  10.   
  11.     // 定義保存所有的Socket  
  12.     public static List<Socket> socketList = new ArrayList<Socket>();  
  13.   
  14.     public static void main(String[] args) throws IOException {  
  15.         ServerSocket server = new ServerSocket(3000);  
  16.         while(true){  
  17.             Socket s=server.accept();  
  18.             socketList.add(s);  
  19.             //每當客戶端連接之後啓動一條ServerThread線程爲該客戶端服務  
  20.             new Thread(new ServiceThreada(s)).start();  
  21.               
  22.         }  
  23.     }  
  24.   
  25. }  


[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.android.net;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.io.OutputStream;  
  7. import java.net.Socket;  
  8.   
  9. public class ServiceThreada implements Runnable {  
  10.   
  11.     // 定義當前線程處理的Socket  
  12.     Socket s = null;  
  13.     // 該線程所處理的Socket所對應的輸入流  
  14.     BufferedReader br = null;  
  15.   
  16.     public ServiceThreada(Socket s) {  
  17.         this.s = s;  
  18.         try {  
  19.             br = new BufferedReader(new InputStreamReader(s.getInputStream()));  
  20.         } catch (IOException e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.     }  
  24.   
  25.     @Override  
  26.     public void run() {  
  27.   
  28.         String content = null;  
  29.         //採用循環不斷的從Socket中讀取客戶端發送過來的數據  
  30.         while((content=readFromClient())!=null){  
  31.             //遍歷socketList中的每個Socket  
  32.             //將讀取到的內容每個向Socket發送一次  
  33.             for(Socket s:MyService.socketList){  
  34.                 OutputStream os;  
  35.                 try {  
  36.                     os = s.getOutputStream();  
  37.                     os.write((content+"\n").getBytes("gbk"));  
  38.                 } catch (IOException e) {  
  39.                     // TODO Auto-generated catch block  
  40.                     e.printStackTrace();  
  41.                 }  
  42.                   
  43.             }  
  44.         }  
  45.   
  46.     }  
  47.   
  48.     // 定義讀取客戶端的信息  
  49.     public String readFromClient() {  
  50.         try {  
  51.             return br.readLine();  
  52.         } catch (Exception e) {  
  53.             e.printStackTrace();  
  54.         }  
  55.         return null;  
  56.     }  
  57.   
  58. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章