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就封裝了這麼多方法,哪裡只要兩行程式碼呢。
不妨看下面的操作
//獲取網路輸入流
java.io.InputStream ins=client.getInputStream();
int t=ins.read();
while(t!=666){
System.out.println("讀到的是 "+t);
t=ins.read();
}
是不是,這些都是檔案儲存的程式碼,移植到網路通訊裡,其實學通訊,相當於重學檔案讀寫。真正要新學的程式碼只有兩行。
上面這幾行程式碼,會一直讀取客戶機傳過來的位元組,直到讀到一個666,才停下。
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,伺服器就呼叫收圓座標的方法
# 總結 其實網路傳輸最重要的是協議,有了協議啥都可以傳