Java網絡通訊之數據的傳輸(一)

        本節來說說網絡數據的傳輸。在網絡信道中,所有數據都只能按字節傳輸。這好比,一棟大樓,先拆成一塊塊磚頭,然後再組合成一棟高樓。拆成磚頭的過程,我們可以稱之爲編碼,組成大樓的過程我可以稱之爲解碼。

      首先我們從最簡單文本傳輸開始說,在文本的傳輸時,我們也要將字符串編碼和解碼;

      編碼:

     String -->byte[]

      String msg = "Hello";

     byte[] data = msg.getBytes("UTF-8");  // GBK

     解碼:

    byte[] --> String    

    byte[] data = new byte[4000];        // 準備一個大點的緩衝區  

    int n = inputStream.read( data );   // 實際收到了N字節    

    String msg  = new String(data, 0, n, "UTF-8");  // 前N字節轉成字符串

值得注意的是,一箇中文字符要佔多少個字節,可能是2個也可能是3個,因爲不同編碼格式佔的字節時不同的。如果是GBK編碼,則佔2個字節,如果是UTF-8則是佔2~3個字節。所以在數據傳輸的時候,也要規定好編碼格式,否則就會出現亂碼情況。比如,用GBK格式編碼,然後用UTF-8的格式解碼,此時就會出現亂碼。

    到此,我們學會了文本的數據的傳輸。下面思考有個問題,那麼對象應該如何傳輸呢。上面我們提到了文本傳輸,我們可以將對象轉成文本然後編碼對其進行傳輸。於是,有一個方案,首先將對象轉成json格式的對象,接着將json對象轉成文本,然後對文件進行編碼,解碼則是逆向過程。舉一個例子,有一個Student對象包含以下信息:

public class Student {     public int id;     public String name;     public boolean sex;     public String cellphone; }

下面我們對這些信息進行傳輸。這個例子需要導入一個第三方jar來處理json格式的數據:json-org-build20180908.jar

Student類

package my;

public class Student
{
	private int id;
	private String name;
	private boolean sex;
	private String cellPhone;
	
	public Student()
	{
		super();
	}

	public Student(int id, String name, boolean sex, String cellPhone)
	{
		super();
		this.id = id;
		this.name = name;
		this.sex = sex;
		this.cellPhone = cellPhone;
	}

	public int getId()
	{
		return id;
	}

	public void setId(int id)
	{
		this.id = id;
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public boolean isSex()
	{
		return sex;
	}

	public void setSex(boolean sex)
	{
		this.sex = sex;
	}

	public String getCellPhone()
	{
		return cellPhone;
	}

	public void setCellPhone(String cellPhone)
	{
		this.cellPhone = cellPhone;
	}

	@Override
	public String toString()
	{
		// TODO Auto-generated method stub
		return "學號:" + this.id + "\r\n" + "姓名:" + this.name + "\r\n性別:" + this.sex + "\r\n手機號碼:" + this.cellPhone + "\r\n";
	}
	

}

 1、首先是服端的代碼

package my;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.json.JSONObject;

public class MyServer 
{

	public static void main(String[] args) throws IOException 
	{
		// TODO Auto-generated method stub
		//建立服務器,服務於2019端口
		ServerSocket serverSock = new ServerSocket(2019);
		System.out.println("服務器啓動,等待連接...");
		while(true)
		{
			//監聽請求,阻塞等待,直到有客戶端發起連接...
			Socket conn = serverSock.accept();
			
			//從連接裏得到輸入輸出流
			//InputStream:可以讀取客戶端發來的數據
			//OutputStream:可以發送數據給客戶端
			InputStream inputStream = conn.getInputStream();
			OutputStream outputStream = conn.getOutputStream();
			
			//接收數據
			byte[] inputData = new byte[4000];
			int n = inputStream.read(inputData);
			if(n <= 0)
			{
				conn.close();
				continue;
			}
			//發送數據
			String inputMsg = new String(inputData , 0 , n , "UTF-8");
			System.out.println("GOT:" + inputMsg);
			
			//將接受到的數據轉換爲學生對象
			JSONObject obj = new JSONObject(inputMsg);
			Student stu = new Student();
			stu.setId(obj.optInt("id" , 0));
			stu.setName(obj.optString("name" , ""));
			stu.setSex(obj.optBoolean("sex" , true));
			stu.setCellPhone(obj.optString("cellPhone" , ""));
			System.out.println("學生:" + stu.toString());
			String outputMsg = "Welcome!";
			byte[] ouputData = outputMsg.getBytes();
			outputStream.write(ouputData);
			System.out.println("ECHO:" + outputMsg + "\n");
			
			//關閉連接
			conn.close();
		}

	}

}

2、客戶端的代碼

package my;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

import org.json.JSONObject;

public class MyClient
{
	public static void main(String[] args) throws IOException
	{
		//一個Scoket代表一路連接
		Socket sock = new Socket();
		//連接至服務器
		sock.connect(new InetSocketAddress("127.0.0.1" , 2019));
		//InputStream用於接收數據,OutputStreet用於發送數據
		InputStream inputStream = sock.getInputStream();
		OutputStream outputStream = sock.getOutputStream();
		
		//發送數據
		//創建一個學生對象
		Student stu = new Student(2018001 , "小明" , true , "18825030000");
		JSONObject json = new JSONObject(stu);
		String outputMsg = json.toString(2);// "Hello";
		byte[] outputData = outputMsg.getBytes("UTF-8");
		outputStream.write(outputData);
		System.out.println(">>" + outputMsg);
		
		//接收數據
		byte[] inputData = new byte[4000];
		int n = inputStream.read(inputData);
		String inputMsg = new String(inputData , 0 , n , "UTF-8");
		System.out.println("<<" + inputMsg);
		
		//關閉連接
		sock.close();
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章