学他人之长,补己之短。转自:http://blog.csdn.net/wuchuanpingstone/article/details/6617276
android客户端通过socket与服务器进行通信可以分为以下几步:
应用程序与服务器通信可以采用两种模式:TCP可靠通信 和UDP不可靠通信。
(1)通过IP地址和端口实例化Socket,请求连接服务器:
socket = new Socket(HOST, PORT); //host:为服务器的IP地址 port:为服务器的端口号
(2)获取Socket流以进行读写,并把流包装进BufferWriter或者PrintWriter:
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
这里涉及了三个类:socket.getOutputStream得到socket的输出字节流,OutputStreamWriter是字节流向字符流转换的桥梁,BufferWriter是字符流,然后再包装进PrintWriter。
(3)对Socket进行读写
if (socket.isConnected()) {
if (!socket.isOutputShutdown()) {
out.println(msg);
}
}
(4)关闭打开的流
out.close();
在写代码的过程中一定要注意对socket 输入流 输出流的关闭
下面是一个简单的例子:
main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent"> 6 7 8 <Button 9 android:id="@+id/connectbtn" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:text="@string/connect" 13 android:gravity="center" 14 android:layout_alignRight="@+id/talkinget" 15 android:layout_alignParentRight="true" /> 16 17 <EditText 18 android:id="@id/talkinget" 19 android:layout_below="@id/connectbtn" 20 android:layout_width="fill_parent" 21 android:editable="false" 22 android:layout_height="200dip" 23 android:scrollHorizontally="true" 24 /> 25 26 27 <Button 28 android:id="@+id/sendbtn" 29 android:layout_width="wrap_content" 30 android:layout_height="wrap_content" 31 android:layout_below="@id/talkinget" 32 android:layout_alignRight="@id/talkinget" 33 android:text="@string/send" 34 /> 35 36 <EditText 37 android:id="@+id/inputet" 38 android:singleLine="true" 39 android:layout_below="@id/talkinget" 40 android:layout_toLeftOf="@id/sendbtn" 41 android:layout_alignBaseline="@id/sendbtn" 42 android:layout_width="fill_parent" 43 android:layout_height="wrap_content" 44 android:hint="@string/inputtip" 45 46 /> 47 </RelativeLayout>
下面是android客户端的源代码:
1 package com.example.socketclientdemo; 2 3 import android.os.Bundle; 4 import android.app.Activity; 5 import android.view.Menu; 6 import java.io.BufferedReader; 7 import java.io.BufferedWriter; 8 import java.io.IOException; 9 import java.io.InputStreamReader; 10 import java.io.OutputStreamWriter; 11 import java.io.PrintWriter; 12 import java.net.Socket; 13 import android.app.AlertDialog; 14 import android.content.DialogInterface; 15 import android.os.Handler; 16 import android.os.Message; 17 import android.view.View; 18 import android.widget.Button; 19 import android.widget.EditText; 20 21 public class SocketDemo extends Activity implements Runnable { 22 private EditText tv_msg = null; 23 private EditText ed_msg = null; 24 private Button btn_send = null; 25 private Button btn_con = null; 26 27 // private Button btn_login = null; 28 private static final String HOST = "10.0.2.2"; 29 private static final int PORT = 9999; 30 private Socket socket = null; 31 private BufferedReader in = null; 32 private PrintWriter out = null; 33 private String content = ""; 34 35 /** Called when the activity is first created. */ 36 @Override 37 public void onCreate(Bundle savedInstanceState) { 38 super.onCreate(savedInstanceState); 39 setContentView(R.layout.main); 40 41 tv_msg = (EditText) findViewById(R.id.talkinget); 42 ed_msg = (EditText) findViewById(R.id.inputet); 43 btn_con = (Button) findViewById(R.id.connectbtn); 44 btn_send = (Button) findViewById(R.id.sendbtn); 45 46 // try { 47 // socket = new Socket(HOST, PORT); 48 // in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 49 // out = new PrintWriter(new BufferedWriter(new OutputStreamWriter( 50 // socket.getOutputStream())), true); 51 // } catch (IOException ex) { 52 // ex.printStackTrace(); 53 // ShowDialog("login exception" + ex.getMessage()); 54 // } 55 btn_send.setOnClickListener(new Button.OnClickListener() { 56 57 @Override 58 public void onClick(View v) { 59 // TODO Auto-generated method stub 60 String msg = ed_msg.getText().toString(); 61 if (socket.isConnected()) { 62 if (!socket.isOutputShutdown()) { 63 out.println(msg); 64 } 65 } 66 } 67 }); 68 69 70 btn_con.setOnClickListener(new Button.OnClickListener() { 71 72 @Override 73 public void onClick(View v) { 74 // TODO Auto-generated method stub 75 new Thread(SocketDemo.this).start(); 76 } 77 }); 78 79 80 //new Thread(SocketDemo.this).start(); 81 } 82 83 public void ShowDialog(String msg) { 84 new AlertDialog.Builder(this).setTitle("notification").setMessage(msg) 85 .setPositiveButton("ok", new DialogInterface.OnClickListener() { 86 87 @Override 88 public void onClick(DialogInterface dialog, int which) { 89 // TODO Auto-generated method stub 90 91 } 92 }).show(); 93 } 94 95 public void run() { 96 97 try { 98 socket = new Socket(HOST, PORT); 99 in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 100 out = new PrintWriter(new BufferedWriter(new OutputStreamWriter( 101 socket.getOutputStream())), true); 102 } catch (IOException ex) { 103 ex.printStackTrace(); 104 ShowDialog("login exception" + ex.getMessage()); 105 } 106 107 try { 108 while (true) { 109 if (socket.isConnected()) { 110 if (!socket.isInputShutdown()) { 111 if ((content = in.readLine()) != null) { 112 content += " "; 113 mHandler.sendMessage(mHandler.obtainMessage()); 114 } else { 115 116 } 117 } 118 } 119 } 120 } catch (Exception e) { 121 e.printStackTrace(); 122 } 123 } 124 125 public Handler mHandler = new Handler() { 126 public void handleMessage(Message msg) { 127 super.handleMessage(msg); 128 tv_msg.setText(tv_msg.getText().toString() + content); 129 } 130 }; 131 132 @Override 133 public boolean onCreateOptionsMenu(Menu menu) { 134 // Inflate the menu; this adds items to the action bar if it is present. 135 getMenuInflater().inflate(R.menu.socket_demo, menu); 136 return true; 137 } 138 139 }
下面是服务器端得java代码:
1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.IOException; 4 import java.io.InputStreamReader; 5 import java.io.OutputStreamWriter; 6 import java.io.PrintWriter; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 import java.util.ArrayList; 10 import java.util.List; 11 import java.util.concurrent.ExecutorService; 12 import java.util.concurrent.Executors; 13 14 15 public class Main { 16 private static final int PORT = 9999; 17 private List<Socket> mList = new ArrayList<Socket>(); 18 private ServerSocket server = null; 19 private ExecutorService mExecutorService = null; //thread pool 20 21 public static void main(String[] args) { 22 new Main(); 23 } 24 public Main() { 25 try { 26 server = new ServerSocket(PORT); 27 mExecutorService = Executors.newCachedThreadPool(); //create a thread pool 28 System.out.print("server start ..."); 29 Socket client = null; 30 while(true) { 31 client = server.accept(); 32 mList.add(client); 33 mExecutorService.execute(new Service(client)); //start a new thread to handle the connection 34 } 35 }catch (Exception e) { 36 e.printStackTrace(); 37 } 38 } 39 class Service implements Runnable { 40 private Socket socket; 41 private BufferedReader in = null; 42 private String msg = ""; 43 44 public Service(Socket socket) { 45 this.socket = socket; 46 try { 47 in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 48 msg = "user" +this.socket.getInetAddress() + "come toal:" 49 +mList.size(); 50 this.sendmsg(); 51 } catch (IOException e) { 52 e.printStackTrace(); 53 } 54 55 } 56 57 @Override 58 public void run() { 59 // TODO Auto-generated method stub 60 try { 61 while(true) { 62 if((msg = in.readLine())!= null) { 63 if(msg.equals("exit")) { 64 System.out.println("ssssssss"); 65 mList.remove(socket); 66 in.close(); 67 msg = "user:" + socket.getInetAddress() 68 + "exit total:" + mList.size(); 69 socket.close(); 70 this.sendmsg(); 71 break; 72 } else { 73 msg = socket.getInetAddress() + ":" + msg; 74 this.sendmsg(); 75 } 76 } 77 } 78 } catch (Exception e) { 79 e.printStackTrace(); 80 } 81 } 82 83 public void sendmsg() { 84 System.out.println(msg); 85 int num =mList.size(); 86 for (int index = 0; index < num; index ++) { 87 Socket mSocket = mList.get(index); 88 PrintWriter pout = null; 89 try { 90 pout = new PrintWriter(new BufferedWriter( 91 new OutputStreamWriter(mSocket.getOutputStream())),true); 92 pout.println(msg); 93 }catch (IOException e) { 94 e.printStackTrace(); 95 } 96 } 97 } 98 } 99 }
注意在AndroidManifest.xml中加入对网络的访问权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
在写代码的过程中一定要注意对套接字和输入/输出流的关闭