日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

java socket android_Android:这是一份很详细的Socket使用攻略

發布時間:2023/12/10 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java socket android_Android:这是一份很详细的Socket使用攻略 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

Socket的使用在 Android網絡編程中非常重要

今天我將帶大家全面了解 Socket 及 其使用方法

目錄

示意圖

1.網絡基礎

閱讀本文前,請先了解 關于計算機網絡基礎,如計算機體系結構、TCP、UDP等知識

2. Socket定義

即套接字,是應用層 與 TCP/IP 協議族通信的中間軟件抽象層,表現為一個封裝了 TCP / IP協議族 的編程接口(API)

示意圖

Socket不是一種協議,而是一個編程調用接口(API),屬于傳輸層(主要解決數據如何在網絡中傳輸)

即:通過Socket,我們才能在Andorid平臺上通過 TCP/IP協議進行開發

對用戶來說,只需調用Socket去組織數據,以符合指定的協議,即可通信

成對出現,一對套接字:

Socket ={(IP地址1:PORT端口號),(IP地址2:PORT端口號)}

一個 Socket 實例 唯一代表一個主機上的一個應用程序的通信鏈路

3. 建立Socket連接過程

示意圖

4. 原理

Socket的使用類型主要有兩種:

流套接字(streamsocket) :基于 TCP協議,采用 流的方式 提供可靠的字節流服務

數據報套接字(datagramsocket):基于 UDP協議,采用 數據報文 提供數據打包發送的服務

具體原理圖如下:

原理圖

5. Socket 與 Http 對比

Socket屬于傳輸層,因為 TCP / IP協議屬于傳輸層,解決的是數據如何在網絡中傳輸的問題

HTTP協議 屬于 應用層,解決的是如何包裝數據

由于二者不屬于同一層面,所以本來是沒有可比性的。但隨著發展,默認的Http里封裝了下面幾層的使用,所以才會出現Socket & HTTP協議的對比:(主要是工作方式的不同):

Http:采用 請求—響應 方式。

即建立網絡連接后,當 客戶端 向 服務器 發送請求后,服務器端才能向客戶端返回數據。

可理解為:是客戶端有需要才進行通信

Socket:采用 服務器主動發送數據 的方式

即建立網絡連接后,服務器可主動發送消息給客戶端,而不需要由客戶端向服務器發送請求

可理解為:是服務器端有需要才進行通信

6. 使用步驟

Socket可基于TCP或者UDP協議,但TCP更加常用

所以下面的使用步驟 & 實例的Socket將基于TCP協議

// 步驟1:創建客戶端 & 服務器的連接

// 創建Socket對象 & 指定服務端的IP及端口號

Socket socket = new Socket("192.168.1.32", 1989);

// 判斷客戶端和服務器是否連接成功

socket.isConnected());

// 步驟2:客戶端 & 服務器 通信

// 通信包括:客戶端 接收服務器的數據 & 發送數據 到 服務器

// 步驟1:創建輸入流對象InputStream

InputStream is = socket.getInputStream()

// 步驟2:創建輸入流讀取器對象 并傳入輸入流對象

// 該對象作用:獲取服務器返回的數據

InputStreamReader isr = new InputStreamReader(is);

BufferedReader br = new BufferedReader(isr);

// 步驟3:通過輸入流讀取器對象 接收服務器發送過來的數據

br.readLine();

// 步驟1:從Socket 獲得輸出流對象OutputStream

// 該對象作用:發送數據

OutputStream outputStream = socket.getOutputStream();

// 步驟2:寫入需要發送的數據到輸出流對象中

outputStream.write(("Carson_Ho"+"\n").getBytes("utf-8"));

// 特別注意:數據的結尾加上換行符才可讓服務器端的readline()停止阻塞

// 步驟3:發送數據到服務端

outputStream.flush();

// 步驟3:斷開客戶端 & 服務器 連接

os.close();

// 斷開 客戶端發送到服務器 的連接,即關閉輸出流對象OutputStream

br.close();

// 斷開 服務器發送到客戶端 的連接,即關閉輸入流讀取器對象BufferedReader

socket.close();

// 最終關閉整個Socket連接

7. 具體實例

實例 Demo 代碼包括:客戶端 & 服務器

本文著重講解客戶端,服務器僅采用最簡單的寫法進行展示

7.1 客戶端 實現

步驟1:加入網絡權限

步驟2:主布局界面設置

包括創建Socket連接、客戶端 & 服務器通信的按鈕

android:id="@+id/connect"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="connect" />

android:id="@+id/disconnect"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="disconnect" />

android:id="@+id/receive_message"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

android:id="@+id/Receive"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="Receive from message" />

android:id="@+id/edit"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

android:id="@+id/send"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="send"/>

步驟3:創建Socket連接、客戶端 & 服務器通信

具體請看注釋

MainActivity.java

package scut.carson_ho.socket_carson;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.net.Socket;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class MainActivity extends AppCompatActivity {

/**

* 主 變量

*/

// 主線程Handler

// 用于將從服務器獲取的消息顯示出來

private Handler mMainHandler;

// Socket變量

private Socket socket;

// 線程池

// 為了方便展示,此處直接采用線程池進行線程管理,而沒有一個個開線程

private ExecutorService mThreadPool;

/**

* 接收服務器消息 變量

*/

// 輸入流對象

InputStream is;

// 輸入流讀取器對象

InputStreamReader isr ;

BufferedReader br ;

// 接收服務器發送過來的消息

String response;

/**

* 發送消息到服務器 變量

*/

// 輸出流對象

OutputStream outputStream;

/**

* 按鈕 變量

*/

// 連接 斷開連接 發送數據到服務器 的按鈕變量

private Button btnConnect, btnDisconnect, btnSend;

// 顯示接收服務器消息 按鈕

private TextView Receive,receive_message;

// 輸入需要發送的消息 輸入框

private EditText mEdit;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

/**

* 初始化操作

*/

// 初始化所有按鈕

btnConnect = (Button) findViewById(R.id.connect);

btnDisconnect = (Button) findViewById(R.id.disconnect);

btnSend = (Button) findViewById(R.id.send);

mEdit = (EditText) findViewById(R.id.edit);

receive_message = (TextView) findViewById(R.id.receive_message);

Receive = (Button) findViewById(R.id.Receive);

// 初始化線程池

mThreadPool = Executors.newCachedThreadPool();

// 實例化主線程,用于更新接收過來的消息

mMainHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case 0:

receive_message.setText(response);

break;

}

}

};

/**

* 創建客戶端 & 服務器的連接

*/

btnConnect.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

// 利用線程池直接開啟一個線程 & 執行該線程

mThreadPool.execute(new Runnable() {

@Override

public void run() {

try {

// 創建Socket對象 & 指定服務端的IP 及 端口號

socket = new Socket("192.168.1.172", 8989);

// 判斷客戶端和服務器是否連接成功

System.out.println(socket.isConnected());

} catch (IOException e) {

e.printStackTrace();

}

}

});

}

});

/**

* 接收 服務器消息

*/

Receive.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

// 利用線程池直接開啟一個線程 & 執行該線程

mThreadPool.execute(new Runnable() {

@Override

public void run() {

try {

// 步驟1:創建輸入流對象InputStream

is = socket.getInputStream();

// 步驟2:創建輸入流讀取器對象 并傳入輸入流對象

// 該對象作用:獲取服務器返回的數據

isr = new InputStreamReader(is);

br = new BufferedReader(isr);

// 步驟3:通過輸入流讀取器對象 接收服務器發送過來的數據

response = br.readLine();

// 步驟4:通知主線程,將接收的消息顯示到界面

Message msg = Message.obtain();

msg.what = 0;

mMainHandler.sendMessage(msg);

} catch (IOException e) {

e.printStackTrace();

}

}

});

}

});

/**

* 發送消息 給 服務器

*/

btnSend.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

// 利用線程池直接開啟一個線程 & 執行該線程

mThreadPool.execute(new Runnable() {

@Override

public void run() {

try {

// 步驟1:從Socket 獲得輸出流對象OutputStream

// 該對象作用:發送數據

outputStream = socket.getOutputStream();

// 步驟2:寫入需要發送的數據到輸出流對象中

outputStream.write((mEdit.getText().toString()+"\n").getBytes("utf-8"));

// 特別注意:數據的結尾加上換行符才可讓服務器端的readline()停止阻塞

// 步驟3:發送數據到服務端

outputStream.flush();

} catch (IOException e) {

e.printStackTrace();

}

}

});

}

});

/**

* 斷開客戶端 & 服務器的連接

*/

btnDisconnect.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

try {

// 斷開 客戶端發送到服務器 的連接,即關閉輸出流對象OutputStream

outputStream.close();

// 斷開 服務器發送到客戶端 的連接,即關閉輸入流讀取器對象BufferedReader

br.close();

// 最終關閉整個Socket連接

socket.close();

// 判斷客戶端和服務器是否已經斷開連接

System.out.println(socket.isConnected());

} catch (IOException e) {

e.printStackTrace();

}

}

});

}

}

7.2 服務器 實現

因本文主要講解客戶端,所以服務器僅僅是為了配合客戶端展示;

為了簡化服務器使用,此處采用Mina框架

服務器代碼請在eclipse平臺運行

按照我的步驟一步步實現就可以無腦運行了

步驟1:導入Mina包

示意圖

步驟2:創建服務器線程

TestHandler.java

package mina;

// 導入包

public class TestHandler extends IoHandlerAdapter {

@Override

public void exceptionCaught(IoSession session, Throwable cause) throws Exception {

System.out.println("exceptionCaught: " + cause);

}

@Override

public void messageReceived(IoSession session, Object message) throws Exception {

System.out.println("recieve : " + (String) message);

session.write("hello I am server");

}

@Override

public void messageSent(IoSession session, Object message) throws Exception {

}

@Override

public void sessionClosed(IoSession session) throws Exception {

System.out.println("sessionClosed");

}

@Override

public void sessionOpened(IoSession session) throws Exception {

System.out.println("sessionOpen");

}

@Override

public void sessionIdle(IoSession session, IdleStatus status) throws Exception {

}

}

步驟3:創建服務器主代碼

TestHandler.java

package mina;

import java.io.IOException;

import java.net.InetSocketAddress;

import org.apache.mina.filter.codec.ProtocolCodecFilter;

import org.apache.mina.filter.codec.textline.TextLineCodecFactory;

import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class TestServer {

public static void main(String[] args) {

NioSocketAcceptor acceptor = null;

try {

acceptor = new NioSocketAcceptor();

acceptor.setHandler(new TestHandler());

acceptor.getFilterChain().addLast("mFilter", new ProtocolCodecFilter(new TextLineCodecFactory()));

acceptor.setReuseAddress(true);

acceptor.bind(new InetSocketAddress(8989));

} catch (Exception e) {

e.printStackTrace();

}

}

}

至此,客戶端 & 服務器的代碼均實現完畢。

7.3 測試結果

點擊 Connect按鈕: 連接成功

示意圖

輸入發送的消息,點擊 Send 按鈕發送

示意圖

服務器接收到客戶端發送的消息

示意圖

點擊 Receive From Message按鈕,客戶端 讀取 服務器返回的消息

示意圖

點擊 DisConnect按鈕,斷開 客戶端 & 服務器的連接

客戶端示意圖

服務器示意圖

7.4 源碼地址

8. 總結

相信大家已經非常了解關于Socket的使用

下面我將繼續對 Android 的網絡編程進行講解,感興趣的同學可以繼續關注本人運營的Wechat Public Account:

請點贊!因為你的鼓勵是我寫作的最大動力!

不定期分享關于安卓開發的干貨,追求短、平、快,但卻不缺深度。

總結

以上是生活随笔為你收集整理的java socket android_Android:这是一份很详细的Socket使用攻略的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。