android udp tcp传输文件,Android使用Socket(Tcp/Udp)協議進行數據傳輸(傳輸大文件)

Socket是什么:所謂Socket 通常也稱作”套接字”,用於描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過”套接字”向網絡發出請求或者應答網絡請求。Socket內部又有兩種協議(Tcp/Udp),我們來說說其各自的特點。

先來說說網絡編程的三要素1.IP地址:網絡中計算機的唯一標識

2.端口

3.協議:通信的規則

Tcp/Udp特點

一、 TCP(協議):

建立連接,形成傳輸數據的通道

在連接中進行大數據量傳輸

通過三次握手完成連接,是可靠協議

必須建立連接,效率稍微低點

二. UDP(協議):

將數據及源和目的封裝在數據包中,不需要建立連接

每個數據包的大小限制在64K內

因無連接,是不可靠協議

不需要建立連接,速度快

Socket工作圖解

c323807bd68de1c7d2111547497b34ce.png

TCP協議進行數據傳輸,實現兩台設備的一個簡單數據發送。

客戶端發送數據/**

*@param serverAddress 要發送到服務端的ip

* 1.創建socket並指定ip和端口號

* 2.獲取輸出流,寫數據

* 3.釋放資源

* 4.Tcp一定要先開接收端

*/

public void send_tcp(String serverAddress) {

try {

Socket s = new Socket(serverAddress, WIFIAdmin.PORT);

//為了發送數據,應該獲得socket流中的輸出流

OutputStream out = s.getOutputStream();

out.write((content.getText().toString()).getBytes());

s.close();

} catch (UnknownHostException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

服務端接收數據/**

* TCP協議接收數據

* 1.創建接收端的Socket對象

* 2.監聽客戶端接收,返回一個Socket對象

* 3.獲取輸入流,讀取數據顯示在控制台

* 4.釋放資源

*/

public void receive_tcp() {

try {

//1.建立連接,監聽端口

ServerSocket ss = new ServerSocket(WIFIAdmin.PORT);

//2.連接客戶端對象

while (true) {

//阻塞式方法,只有客戶端連接了才會繼續往下運行

Socket accept = ss.accept();

//獲取ip

String ip = accept.getInetAddress().getHostAddress();

//3.獲取客戶端發送過來的數據

InputStream in = accept.getInputStream();

//4.開始讀取,獲取輸入信息

BufferedReader bff = new BufferedReader(new InputStreamReader(in));

//讀取信息

String line;

final StringBuilder sb = new StringBuilder();

while ((line = bff.readLine()) != null) {

sb.append(line);

}

Message message = new Message();

message.obj = sb.toString();

handler.sendMessage(message);

//5.關閉

//ss.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

現在來看下UDP協議是怎么進行數據傳輸的。

先來看下發送端/*

* UDP協議發送數據:

* 1.創建發送端Socket對象

* 2.創建數據,並把數據打包

* 3.調用Socket對象發送方法發送數據包

* 4.釋放資源

*/

private void udpSendMessage() {

DhcpInfo info = wifiManager.getDhcpInfo();

String serverAddress = WIFIAdmin.intToIp(info.serverAddress);

// 創建發送端Socket對象

try {

// 創建發送端Socket對象

DatagramSocket ds = new DatagramSocket();

// 創建數據,並把數據打包

byte[] bys = content.getText().toString().getBytes();

DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName(serverAddress),

WIFIAdmin.UDP_PORT);

// 調用Socket對象發送方法發送數據包

ds.send(dp);

// 釋放資源

ds.close();

} catch (Exception e) {

e.printStackTrace();

}

}

在瞄一下接收端/*

* UDP協議接收數據:

* 1.創建接收端Socket對象

* 2.創建一個數據包(接收容器)

* 3.調用Socket對象接收方法接收數據包

* 4.解析數據包

* 5.釋放資源

*/

private void receive_udp() {

try {

// 創建接收端Socket對象

DatagramSocket ds = new DatagramSocket(WIFIAdmin.UDP_PORT);

// 創建一個數據包(接收容器)

byte[] bys = new byte[1024];

DatagramPacket dp = new DatagramPacket(bys, bys.length);

// 調用Socket對象接收方法接收數據包

ds.receive(dp);

// 獲取對方的ip

String ip = dp.getAddress().getHostAddress();

// 解析數據

String data = new String(dp.getData(), 0, dp.getLength());

Message message = new Message();

message.obj = data;

message.what = 2;

handler.sendMessage(message);

ds.close();

} catch (Exception e) {

e.printStackTrace();

}

}

使用Tcp協議傳輸大文件,循環將數據寫入流中(Tcp發送端)/*

* @param path 文件路徑

* @param FileName 文件名

*/

public void sendFile(String path, String FileName) {

DhcpInfo info = wifiManager.getDhcpInfo();

serverAddress = WifiAdmin.intToIp(info.serverAddress);

Socket s = new Socket(serverAddress, PORT);

OutputStream out = s.getOutputStream();

//將文件名寫在流的頭部以#分割

out.write((FileName + "#").getBytes());

FileInputStream inputStream = new FileInputStream(new File(path));

byte[] buf = new byte[1024];

int len;

//判斷是否讀到文件末尾

while ((len = inputStream.read(buf)) != -1) {

out.write(buf, 0, len);//將文件循環寫入輸出流

}

//告訴服務端,文件已傳輸完畢

s.shutdownOutput();

//獲取從服務端反饋的信息

BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));

String serverBack = in.readLine();

Log.d("TAG", serverBack);

//資源關閉

s.close();

inputStream.close();

} catch (Exception e) {

e.printStackTrace();

}

}

大文件傳輸(Tcp接收端)public synchronized void receiveFile() {

try {

ServerSocket ss = new ServerSocket(WifiAdmin.PORT);

while (true) {

Socket socket = ss.accept();

InputStream in = socket.getInputStream();

int content;

//裝載文件名的數組

byte[] c = new byte[1024];

//解析流中的文件名,也就是開頭的流

for (int i = 0; (content = in.read()) != -1; i++) {

//表示文件名已經讀取完畢

if (content == '#') {

break;

}

c[i] = (byte) content;

}

//將byte[]轉化為字符,也就是我們需要的文件名

String FileName = new String(c, "utf-8").trim();

//創建一個文件,指定保存路徑和剛才傳輸過來的文件名

OutputStream saveFile = new FileOutputStream(

new File(Environment.getExternalStorageDirectory().toString(), FileName));

byte[] buf = new byte[1024];

int len;

//判斷是否讀到文件末尾

while ((len = in.read(buf)) != -1) {

saveFile.write(buf, 0, len);

}

saveFile.flush();

saveFile.close();

//告訴發送端我已經接收完畢

OutputStream outputStream = socket.getOutputStream();

outputStream.write("文件接收成功".getBytes());

outputStream.flush();

outputStream.close();

socket.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}

掌握了Socket的基本傳輸規則,相信你很快就能寫出一個利用局域網讓兩台設備進行數據傳輸了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值