Android用戶端與本機伺服器Socket通訊

來源:互聯網
上載者:User

標籤:stream   input   服務端   super   public   strong   響應   xtend   圖片   

Android用戶端與本機伺服器Socket通訊

Socket伺服器運行結果圖??

一.用戶端和伺服器端的選擇:
  • 用戶端是我們手機端,關於伺服器端,只要安裝了JDK,自然就擁有通訊的功能,我們只需要在Eclipse或者MyEclipse中寫好文章中伺服器端的代碼,運行起來即可,用accept()方法啟動伺服器端,等待用戶端的串連,在未串連的情況下,伺服器端處於堵塞的狀態。
二.用戶端注意事項
  • andriod用戶端添加網路存取權限
    <uses-permission android:name="android.permission.INTERNET" />

  • 對Socket的操作放在非UI線程內進行

  • 要使用正確的IP地址和連接埠號碼連接埠號碼的範圍是0~65535,1024一下的連接埠被系統分給了一些服務,在cmd視窗執行netstat -ano命令可以看到所有連接埠的使用方式

  • 真機進行調試(1、串連上手機,手機開啟adb。步驟:設定> 應用程式> 開發>選擇USB調試;usb選項有些不可見,具體百度),指定Server的IP地址,此地址為區域網路地址,如果是使用WIFI上網,則為PC機的WIFI IP。中串連的第二個就是樣本
    三.Socket通訊
  • 利用ip地址+連接埠號碼唯一標示網路中的一個進程,能夠唯一標示網路中的進程後,它們就可以利用socket進行通訊。

  • socket是在應用程式層和傳輸層之間的一個抽象層,它把TCP/IP層複雜的操作抽象為幾個簡單的介面供應用程式層調用,實現進程在網路中通訊。

  • socket是"開啟—讀/寫—關閉"模式的實現(只能讀取對方放在流中的資料),以使用TCP協議通訊的socket為例,其互動流程大概是這樣子的

  • Socket有兩種主要的操作方式:連線導向的和不需連線的,即TCP和UDP。
      連線導向的Socket操作就像一部電話,Socket必須在發送資料之前與目的地的Socket取得串連,一旦串連建立了,Socket就可以使用一個流介面進行開啟、讀寫以及關閉操作。並且,所有發送的資料在另一端都會以相同的順序被接收。

  • 不需連線的Socket操作就像一個郵件投遞,每一個資料報都是一個獨立的單元,它包含了這次投遞的所有資訊(目的地址和要發送的內容)。在這個模式下的Socket不需要串連目的地Socket,它只是簡單的投出資料報。
    四.TCP串連與HTTP串連與Socket串連的區別
  • TCP串連與HTTP串連的區別

HTTP是基於TCP的,用戶端往服務端發送一個HTTP請求時第一步就是要建立與服務端的TCP串連。

  • TCP串連與Socket串連的區別:

socket層只是在TCP/UDP傳輸層上做的一個抽象介面層,基於TCP協議的socket串連同樣需要通過三向交握建立串連,是可靠的;基於UDP協議的socket串連不需要建立串連的過程,不過對方能不能收到都會發送過去,是不可靠的,大多數的即時通訊IM都是後者。

  • HTTP串連與Socket串連的區別

HTTP是短串連,Socket(基於TCP協議的)是長串連。儘管HTTP1.1開始支援持久串連,但仍無法保證始終串連。而Socket串連一旦建立TCP三向交握,除非一方主動斷開,否則串連狀態一直保持。

HTTP串連服務端無法主動發訊息。決定二者分別適合應用在什麼情境下。HTTP採用“要求-回應”機制,必須滿足用戶端發送訊息在前,服務端回複在後。Socket串連雙方類似peer2peer的關係,一方隨時可以向另一方喊話。

  • 什麼時候該用HTTP,什麼時候該用socket

用HTTP的情況:雙方不需要時刻保持串連線上,比如用戶端資源的擷取、檔案上傳等。

用Socket的情況:大部分即時通訊應用(QQ、)、聊天室、蘋果APNs等。

五.socket代碼

用戶端代碼

public class MainActivity extends AppCompatActivity {//IP地址和連接埠號碼public static String IP_ADDRESS = "192.168.1.106";public static int PORT = 2346;//三個控制項EditText text = null;Button connect = null;TextView info = null;//handlerHandler handler = null;Socket soc = null;DataOutputStream dos = null;DataInputStream dis = null;String messageRecv = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    text = (EditText) findViewById(R.id.editText);    connect = (Button) findViewById(R.id.buttonConnection);    info = (TextView) findViewById(R.id.info);    connect.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            new ConnectionThread(text.getText().toString()).start();        }    });    handler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            Bundle b = msg.getData();  //擷取訊息中的Bundle對象            String str = b.getString("data");  //擷取鍵為data的字串的值            info.append(str);        }    }; }            //建立一個子線程,實現socket通訊    class ConnectionThread extends Thread {    String message = null;    public ConnectionThread(String msg) {        message = msg;    }    @Override    public void run() {        if (soc == null) {            try {                //Log.d("socket","new socket");                soc = new Socket(IP_ADDRESS, PORT);                //擷取socket的輸入輸出資料流                dis = new DataInputStream(soc.getInputStream());                dos = new DataOutputStream(soc.getOutputStream());            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        try {            dos.writeUTF(message);            dos.flush();            messageRecv = dis.readUTF();//如果沒有收到資料,會阻塞            Message msg = new Message();            Bundle b = new Bundle();            b.putString("data", messageRecv);            msg.setData(b);            handler.sendMessage(msg);        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}}

`
伺服器端代碼

public class Server {ServerSocket serverSocket = null;public final int port = 2346;public Server(){        //輸出伺服器的IP地址        try {            InetAddress addr = InetAddress.getLocalHost();            System.out.println("local host:"+addr);            serverSocket = new ServerSocket(port);            System.out.println("0k");        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }}public void startService(){    try {        Socket socket = null;        System.out.println("waiting...");        //等待串連,每建立一個串連,就建立一個線程        while(true){                            socket = serverSocket.accept();//等待一個用戶端的串連,在串連之前,此方法是阻塞的            System.out.println("connect to"+socket.getInetAddress()+":"+socket.getLocalPort());            new ConnectThread(socket).start();        }    } catch (IOException e) {        // TODO Auto-generated catch block        System.out.println("IOException");        e.printStackTrace();    }}//向用戶端發送資訊class ConnectThread extends Thread{    Socket socket = null;    public ConnectThread(Socket socket){            super();        this.socket = socket;    }    @Override    public void run(){        try {            DataInputStream dis = new DataInputStream(socket.getInputStream());            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());            while(true){                String msgRecv = dis.readUTF();                System.out.println("msg from client:"+msgRecv);                dos.writeUTF("received:"+msgRecv);                dos.flush();            }        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}public static void main(String[] args) {    // TODO Auto-generated method stub    new Server().startService();}}
代碼的邏輯

用戶端 :

  1. 初始化控制項,並綁定監聽器,編寫按鈕的事件處理代碼。

  2. 在事件處理代碼中開啟子線程,子線程中通過Sockt訪問伺服器。
  3. 利用非同步訊息處理機制,message對象將子線程的資料傳回handle的處理方法更新UI。

服務端

  1. serversocket對象監聽等待,利用迴圈當有客戶訪問就開啟子線程處理傳訊息回用戶端。(模擬器和手機同時通過區域網路訪問)
    最後的廢話
  1. 搞電腦必須得有理論指導實踐,否則只能像個沒頭蒼蠅到處亂撞,我的電腦網路知識真的是一言難盡。

  2. 各大語言的官網是個好東西。豐富的資料和教程簡直讓人沉醉其中不能自拔。雖然比不上網路小說通俗易懂,但是引人入勝一點也不差。
  3. 不會的東西太多,用Google外掛程式等工具列表,先解決主要的,平時有想法也可以記錄。

  4. 用部落格整理自己的知識,形成體系。看得再多不如編一遍。

PS. 整合了很多地方的知識點,官網,博主,就不一一記錄原地址了。

2018-05-13 22:15:53 星期日

Android用戶端與本機伺服器Socket通訊

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.