這篇博文介紹基於TCP協議來進行資料的發送,通常用於傳送檔案採用這種方式。
一:TCP協議通訊模型
1:工作流程
首先有兩部分用戶端和伺服器端,用戶端需要Socket這個類的對象,而伺服器端需要ServerSocket這個類的對象,由用戶端Socket發送一個請求,伺服器端的ServerSocket在電腦的某一個連接埠號碼上進行監聽,監聽用戶端發送的請求之後,那麼用戶端和伺服器端的一個通訊通道就建立起來了,這時候呢既可以從用戶端向伺服器端發送資料,伺服器端也可以給用戶端相應的響應。在用戶端發送資料的時候我們需要用到IO流裡面的OutputStream,通過這個OutputStream把資料發送給伺服器端,伺服器端用InputStream來讀取用戶端當中用OutputStream所寫入的資料。生活舉例:就像雙方男女朋友打電話一樣,男孩(用戶端)說話(資料)通過耳機發送到電話網路中去,當男孩說話的時候就相當於咱們這裡的通過OutputStream向互連網中寫入資料,而作為接聽的這個女孩(伺服器端)那麼男孩(用戶端)說的內容就是女孩(伺服器端)聽到的內容,那麼就是說伺服器端可以通過InputStream把用戶端當中通過OutputStream所寫入的資料給它讀取出來,反之亦然,如果伺服器端想向用戶端發送資料,那麼就使用OutputStream寫出資料,在用戶端通過InputStream把伺服器端當中通過OutputStream所寫入的資料給它讀取出來。就像打電話一樣,你說的就是我聽的,你聽的就是我說的。
二:通過基於TCP協議發送和讀取資料
1:布局檔案main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="啟動監聽線程"
android:id="@+id/btn1"
/>
</LinearLayout>
2.1:伺服器端Socket代碼檔案MainActivity.java
package com.szy.socket;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MainActivity extends Activity
{
private Button btn1 = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn1 = (Button) findViewById(R.id.btn1);
//給按鈕綁定監聽器
btn1.setOnClickListener(new Btn1Listener());
}
//按鈕監聽器
private class Btn1Listener implements OnClickListener
{
@Override
public void onClick(View v)
{
//啟動一個線程
new ServerThread().start();
}
}
//線程類
private class ServerThread extends Thread
{
public void run()
{
//聲明一個ServerSocket對象
ServerSocket serverSocket = null;
try
{
//建立一個ServerSocket對象,並讓ServerSocket在4567連接埠上監聽
serverSocket = new ServerSocket(4567);
//調用 ServerSocket對象的accept()方法接收用戶端所發送的請求
//accept()這個方法是一個阻塞的方法,如果用戶端沒有發送請求,那麼代碼運行到這裡被阻塞,停在這裡不再向下運行了,一直等待accept()函數的返回,這時候突然用戶端發送一個請求,那個這個方法就會返回Socket對象,
//Socket對象代表格服務器端和用戶端之間的一個串連
Socket socket = serverSocket.accept();
//從Socket對象中得到InputStream對象
//一旦通訊管道建立起來後,就是伺服器端有一個Socket,用戶端也有一個Socket,我們就可以通過伺服器端的Socket裡面的InputStream來讀取用戶端所發送的資料
InputStream inputStream = socket.getInputStream();
byte data[] = new byte[1024*4];
int i = 0;
//從InputStream對象中讀取用戶端所發送的資料
while((i = inputStream.read(data)) !=1 )
Log.d("mytag",new String(data,0,i));
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
serverSocket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
}
2.2:用戶端Socket代碼檔案TcpSocketClient.java
package com.szy.socketclient;
import android.app.Activity;
import java.net.Socket;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class TcpSocketClient extends Activity
{
public static void main(String[] args)
{
try
{
//建立一個Socket對象,指定伺服器端的IP地址和連接埠號碼
Socket socket = new Socket("192.168.1.105",4567);
//使用InputStream對象讀取硬碟上的檔案
InputStream inputStream = new FileInputStream("C://www.txt");
//從Socket對象中得到OutputStream對象,準備往OutputStream對象裡寫入資料
OutputStream outputStream = socket.getOutputStream();
byte data[] = new byte[1024*4];
int i = 0;
while((i = inputStream.read(data)) !=1 )
//從InputStream對象中讀取資料並寫入到 OutputStream對象當中
outputStream.write(data, 0, i);
outputStream.flush();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
這樣就等於把http://www.txt/這個檔案通過網路發送給伺服器端了,伺服器端就可以接收到資料了