1. 程式人生 > 其它 >Socket網路連線小白教程

Socket網路連線小白教程

技術標籤:java

文章目錄


前言

用java實現一個簡易的伺服器和客戶機


一、網路連線是什麼?

你的電腦登入qq時,輸入密碼、賬號。電腦通過網線把密碼、賬號發給騰訊的伺服器。騰訊伺服器確認密碼正確,再通過網線傳送登入成功的訊號。這個訊號就是網線中傳輸的電流(光)。

類比人和人說話交流,空氣就是那根網線,聲音——就是網線中的電流——在空氣中傳播。

訊號在網線中傳輸時,不管是電流還是光,只有兩種狀態,通和不通。這剛好與計算機中的0和1對應起來(真是個奇妙的巧合)。
在網路傳輸中,最小的資訊單位是byte,也就是8位。

二、如何建立一個網路連線?

1.伺服器

建立一個能用的伺服器只需要兩行程式碼!

//伺服器建立
java.net.ServerSocket myss = new java.net.ServerSocket(port);
// 等待客戶機連線
java.net.Socket client = myss.accept();

myss就是我們的伺服器
執行my.accept();程序就會停在那裡,直到有客戶機聯進來,就返回一個Socket物件(client),裡面封裝了和客戶機通訊的網路傳輸方法。這個client就相當於一個網路傳輸程式碼塊,所有網路傳輸需要的程式碼都可以在裡面呼叫;
//如有需要也可以自己寫一個Socket類。

這裡展示Socket封裝的其中一些方法。呼叫這些方法就能傳輸任何你想傳的東西。
在這裡插入圖片描述
你可能會問,一個Socket就封裝了這麼多方法,哪裡只要兩行程式碼呢。
不妨看下面的操作

//獲取網路輸入流
java.io.InputStream ins=client.getInputStream();
int t=ins.read();
	while(t!=666){
		System.out.println("讀到的是 "+t);
		t=ins.read();
	} 

是不是,這些都是檔案儲存的程式碼,移植到網路通訊裡,其實學通訊,相當於重學檔案讀寫。真正要新學的程式碼只有兩行。
上面這幾行程式碼,會一直讀取客戶機傳過來的位元組,直到讀到一個666,才停下。

與檔案讀寫相似,上面的程式碼要不報錯,也需要加上try{}chcatch (Exception e) {}

2.客戶機

沒有客戶機連進去,伺服器等於白搭。
這就寫個客戶機:
在while迴圈裡不停給伺服器傳送"efewfe"。

    java.net.Socket client=new java.net.Socket("182.96.241.245",9999);
    //182.96.241.245是伺服器電腦的IP地址;9999是伺服器那個程式的介面。如果是用自己電腦,就把ip改成127.0.0.1
    java.io.OutputStream ous=client.getOutputStream();
    while(true){
		String msgString="efewfe";
		//獲得字串byte[]
		byte[] data=msgString.getBytes();
		//傳送byte[]
		ous.write(data);
		//發給伺服器了
	}

因為不能直接發字串,所以要先轉成byte[]再發送。
這裡還有一個問題,再這個示例中客戶機寫入的是字元,而伺服器讀取的是int,這就造成了資訊傳輸的錯誤。所以客戶機和伺服器一定要商量好要傳什麼,怎麼傳。於是,就產生了網路傳輸協議。

三、什麼是協議?

第二個部分說了一定要商量好怎麼傳才能傳有用的資訊。也就是協議。
比如我要發一條直線,就先寫一個byte 33,再寫4個int代表座標。
客戶機讀取到一個byte為33後,就知道是傳直線了,接下來收四個座標。
就完成一次直線傳輸了。

//客戶機發直線的方法
public void sendPaint(int x1, int y1, int x2, int y2) {
		try {
			dous.writeByte(33);//直線為1
			dous.writeInt(x1);
			dous.writeInt(y1);
			dous.writeInt(x2);
			dous.writeInt(y2);
			System.out.println("傳送一條直線");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

//伺服器判斷是否傳的是直線
while (true) {
		int x = dins.readByte();
		/*
		 * 直線為1 
		 */
		if (x == 1){
			recevPaint(dins);
		}else{
			 System.out.println("亂傳");
		}
	}
//收直線的方法
public void recevPaint(DataInputStream dins) {
		try {
			int x1 = dins.readInt();
			int y1 = dins.readInt();
			int x2 = dins.readInt();
			int y2 = dins.readInt();
			System.out.println("收到一條直線");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

這個先傳的byte33,就是報頭,代表直線,代表它後面有4個int。
同理,可以加個傳圓形的,客戶機傳圓之前先傳個byte33,只要報頭是32,伺服器就呼叫收圓座標的方法


# 總結 其實網路傳輸最重要的是協議,有了協議啥都可以傳