Android网络编程的Socket通信总结
創(chuàng)建服務(wù)器端的步驟:
1,指定端口實(shí)例化一個(gè)ServerSocket
2,調(diào)用ServerSocket的accept方法等待連接期間阻塞
3,獲取位于底層的Socket流進(jìn)行讀寫(xiě)操作
4,將數(shù)據(jù)封裝成流
5,對(duì)Socket進(jìn)行讀寫(xiě)
6,關(guān)閉流
創(chuàng)建客戶端的步驟:
1,通過(guò)IP地址和端口實(shí)例化Socket,請(qǐng)求連接服務(wù)器
2,獲取位于底層的Socket流進(jìn)行讀寫(xiě)操作
3,將數(shù)據(jù)封裝成流(BufferedReader/PrintWriter,DataOutputStream/DataInputStream)的實(shí)例
4,對(duì)Socket進(jìn)行讀寫(xiě)
5,關(guān)閉流
使用ServerSocket創(chuàng)建服務(wù)器端:
public static void main(String[] args) throws IOException {// TODO Auto-generated method stub//創(chuàng)建一個(gè)ServerSo查看特,用于監(jiān)聽(tīng)客戶端Socket的連接請(qǐng)求ServerSocket ss=new ServerSocket(3000);while(true){//每當(dāng)接收到客戶端Socket的請(qǐng)求,服務(wù)器端也對(duì)應(yīng)產(chǎn)生一個(gè)Socket,沒(méi)接收到請(qǐng)求就等待。。Socket s=ss.accept();OutputStream os=s.getOutputStream();//服務(wù)器端產(chǎn)生的Socket獲取輸出流os.write("您好,您收到了來(lái)自服務(wù)器的祝福!\n".getBytes());os.close();s.close();}} 客戶端使用Socket通信:測(cè)試環(huán)境是PC端服務(wù)器,手機(jī)當(dāng)客戶端,PC和手機(jī)要連接同一個(gè)局域網(wǎng),PC和手機(jī)在同一網(wǎng)段
package com.example.simpleclient;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.net.UnknownHostException;import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView;public class MainActivity extends Activity {TextView text;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text=(TextView) findViewById(R.id.text);new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubtry {//建立連接到遠(yuǎn)程服務(wù)器的的Socket,Ip是服務(wù)器端PC的IP,測(cè)試環(huán)境是PC端服務(wù)器,手機(jī)當(dāng)客戶端,PC和手機(jī)要連接同一個(gè)局域網(wǎng),PC和手機(jī)在同一網(wǎng)段Socket socket = new Socket("192.168.88",3000);//將Socket對(duì)應(yīng)的輸入流包裝秤BufferedReaderBufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));String line=br.readLine();text.setText("來(lái)自服務(wù)的數(shù)據(jù):"+line);br.close();socket.close();} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} }}.start();}} <!-- 訪問(wèn)網(wǎng)絡(luò)權(quán)限 --><uses-permission android:name="android.permission.INTERNET"/>
客戶端和服務(wù)器端的輸入輸出流的問(wèn)題容易搞混淆:如下圖
在客戶端:
socket.getInputStream();從socket讀來(lái)自服務(wù)器的數(shù)據(jù)
socket.getOutputStream();向socket中寫(xiě)數(shù)據(jù),傳給服務(wù)器,服務(wù)器在它的socket的輸入流讀這個(gè)數(shù)據(jù)
在服務(wù)器端:
socket.getInputStream();從socket讀來(lái)自客戶端的數(shù)據(jù)
socket.getOutputStream();向socket中寫(xiě)數(shù)據(jù),傳給客戶端,客戶端在它的socket的輸入流讀這個(gè)數(shù)據(jù)
就是說(shuō)客戶端和服務(wù)器端的輸入輸出流是對(duì)應(yīng)的,輸入流連接到輸出流
輸入輸出流的包裝:
第一種方法:數(shù)據(jù)二進(jìn)制流
DataInputStream in=new DataInputStream(socket.getInputStream());//接收客戶端信息 DataOutputStream out=new DataOutputStream(socket.getOutputStream()); //向客戶端發(fā)送消息第二種方法: PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
socketClient,java
Server.java import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket;public class Server {public Server(){new ServerThread().start();}class ServerThread extends Thread{public void run() {try {ServerSocket ss=new ServerSocket(8888); 創(chuàng)建一個(gè)ServerSocket對(duì)象,并讓這個(gè)ServerSocket在8888端口監(jiān)聽(tīng)while(true){Socket socket=ss.accept(); //調(diào)用ServerSocket的accept()方法,接受客戶端所發(fā)送的請(qǐng)求,如果客戶端沒(méi)有發(fā)送數(shù)據(jù),那么該線程就停滯不繼續(xù) // try { // BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //接收客戶端信息 // String readline = in.readLine(); // System.out.println("readline:"+readline); // // PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true); // out.println("link server success"); // // in.close(); //關(guān)閉流 // out.close();//關(guān)閉流 // socket.close();//關(guān)閉打開(kāi)的socket // // } catch (Exception e) { // // TODO: handle exception // }finally{ // // socket.close();// // }try {DataInputStream in=new DataInputStream(socket.getInputStream());//接收客戶端信息String readline=in.readUTF();System.out.println(readline);DataOutputStream out=new DataOutputStream(socket.getOutputStream()); //向客戶端發(fā)送消息out.writeUTF("link server success");out.flush();in.close(); //關(guān)閉流out.close();//關(guān)閉流socket.close();//關(guān)閉打開(kāi)的socket} catch (Exception e) {System.out.println(e.getMessage());}}} catch (IOException e) {System.out.println(e.getMessage());}}}public static void main(String[] args) throws IOException {new Server(); //開(kāi)啟服務(wù)器}}
加入多線程:聊天室
客戶端和服務(wù)器端保持長(zhǎng)時(shí)間的通信,服務(wù)器需要不斷的讀取客戶端數(shù)據(jù),并向客戶端寫(xiě)入數(shù)據(jù),客戶端也需要不斷的讀取服務(wù)器的數(shù)據(jù)
服務(wù)器應(yīng)該為每個(gè)Socket單獨(dú)啟動(dòng)一條線程,每條線程負(fù)責(zé)與一個(gè)客戶端進(jìn)行通信
服務(wù)器端:
package com.hust.multithred;import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList;public class MyServer {/*** @param args* @throws IOException *///服務(wù)器端保存所有Socket的ArrayListpublic static ArrayList<Socket> socketlist=new ArrayList<Socket>();public static void main(String[] args) throws IOException {// TODO Auto-generated method stubServerSocket ss=new ServerSocket(3000);//ServerSocket監(jiān)聽(tīng)3000端口while(true){Socket socket_in_server=ss.accept();//循環(huán)等待客戶端的Socketsocketlist.add(socket_in_server); //每接收到一個(gè)客戶端的Socket,將服務(wù)器端產(chǎn)生的與之對(duì)應(yīng)的Socket加入數(shù)組//為每一個(gè)Socket單獨(dú)啟動(dòng)一條線程,每個(gè)線程負(fù)責(zé)與一個(gè)客戶端進(jìn)行通信SocketThread socketthread=new SocketThread(socket_in_server);new Thread(socketthread).start();}}} package com.hust.multithred;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket;public class SocketThread implements Runnable{//線程任務(wù)類,實(shí)現(xiàn)Runnable接口Socket s=null;BufferedReader br=null;public SocketThread(Socket s) throws IOException{this.s=s;br=new BufferedReader(new InputStreamReader(s.getInputStream()));//Socket輸入流包裝成字符流,來(lái)自客戶端的數(shù)據(jù)在此輸入流上,服務(wù)器端可以讀}public void run() {// TODO Auto-generated method stubtry {String content=null;//循環(huán)不斷沖Socket中讀取客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù)while((content=readFormClient())!=null){//每讀到數(shù)據(jù)之后,將讀到的內(nèi)容向每個(gè)Socket發(fā)送一次for(Socket s:MyServer.socketlist){ OutputStream os=s.getOutputStream();os.write((content+"\n").getBytes("utf-8")); //寫(xiě)到每個(gè)socket 的輸出流上 }}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//從輸入流上讀取來(lái)自客戶端的數(shù)據(jù)方法public String readFormClient(){String content=null;try {content = br.readLine();} catch (IOException e) {// TODO Auto-generated catch blockMyServer.socketlist.remove(s);}return content;}}客戶端:
MainActivity.java
ClientThread.java package com.hust.multithreadclient;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException;import android.os.Handler; import android.os.Looper; import android.os.Message;public class ClientThread implements Runnable {Socket s;Handler handler; //定義向UI線程發(fā)送消息的Handler對(duì)象Handler rvhandler; //定義接收UI線程消息的Handler對(duì)象BufferedReader br=null;OutputStream os=null;public ClientThread(Handler handler){this.handler=handler;}@Overridepublic void run() {// TODO Auto-generated method stubtry {s=new Socket("192.168.1.88",3000);br=new BufferedReader(new InputStreamReader(s.getInputStream()));os=s.getOutputStream();//啟動(dòng)一條子線程來(lái)讀取服務(wù)器端相應(yīng)的數(shù)據(jù)new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubString content=null;try{while((content=br.readLine())!=null){Message msg=new Message();msg.what=0x123;msg.obj=content;handler.sendMessage(msg);//此子線程中僅僅是讀來(lái)自服務(wù)器的數(shù)據(jù),并發(fā)給UI線程的Handler處理}}catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}.start();/** 當(dāng)前客戶端線程中Handler,Android線程之間的通信是Handler來(lái)實(shí)現(xiàn)* 此Hnadler接收UI線程發(fā)過(guò)來(lái)的數(shù)據(jù),即用戶的輸入,并寫(xiě)到輸出流* 因?yàn)榇薍andler是接收處理消息,所以需要使用Looper* */Looper.prepare();rvhandler=new Handler(){@Overridepublic void handleMessage(Message msg) {//如果接收到UI線程中用戶輸入的數(shù)據(jù)if(msg.what==0x111){try{//將用戶在文本框內(nèi)的輸入內(nèi)容寫(xiě)入網(wǎng)絡(luò)os.write((msg.obj.toString()+"\r\n").getBytes("utf-8"));}catch(IOException e){e.printStackTrace(); }}}};Looper.loop();//啟動(dòng)looper} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
總結(jié)
以上是生活随笔為你收集整理的Android网络编程的Socket通信总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 喝汽水
- 下一篇: Android中的JSONObject和