#開頭的廢話#學習java已經半個月了,原本在摳教材里面的字眼時,覺得教材好厚,要看完不知道要到猴年馬月去了。突然在網上看到一個教程,里面老師說學編程語言書不用太細看,看個大概,知道里面講些什么就好,不用全記得,然后你一個勁地編,使勁地編,編的時候不懂再回來看就好了,這是最快的方法。心里一琢磨,還真是這樣,根據以前學C語言的情況不就這樣嗎。所以便加速看,把一些書里介紹的方法,類飛速地瀏覽過了,刷到網絡這一章,覺得socket編程應該是得試一下手,不要只看不做假把式。
此文為原創,轉摘請注明轉摘自http://www.cnblogs.com/liusxg/p/3917624.html
socket編程:
一:什么是socket:socket是BSD UNIX的通信機制,通常稱為“套接字”,其英文原意是“孔”或“插座”。有些顧名思義,socket正如其英文原意一樣,像是一個多孔插座,可以提供多個端口的連接服務。
為了更加直觀的了解socket,可以用插座來比喻socket。
如果說socket是一個多孔插座,插座是提供各種電器供電的地方,不同的電器工作時需要的電壓和電流也不一樣,但各種電器都有各自的一個插口,這個稱之為“端口”。電器使用的電可以看做是網絡資源或者是各種“流”,電是由電線傳輸過來的,所以插座需要連接電線,這里電線也就是服務器和客戶端連接 “connection”。 其中初始化socket的過程像是買來一個插座的安裝過程。
在插座這邊的是“客戶端”,電線那邊提供電的發電廠是“服務器”。客戶端和發電廠都各自擁有一個地址,即“IP地址”。其中還有一套傳輸和用電的規則,比如傳輸電時需要的電線多少伏才能滿足需求,電器用電的技術參數,端口是幾個孔的。這個是“協議”。正常情況下我們是不會去管協議的內容是什么,也就是說協議在我們面前是隱藏的。
下圖可以有一些理解(圖摘自源碼工作室):
二.工作原理:對於服務器來說,服務器先初始化socket,然后端口綁定(bind),再對端口監聽(listen),調用accept阻塞,等待客戶端連接請求。對於客戶端來說,客戶端初始化socket,然后申請連接(connection)。客戶端申請連接,服務器接受申請並且回復申請許可(這里要涉及TCP三次握手連接),然后發送數據,最后關閉連接,這是一次交互過程。
如下圖(圖摘自源碼工作室):
客戶端Client源碼如下:
1 import java.io.*; 2 import java.net.*; 3 4 public class Client { 5 6 public static void main(String[] args) throws Exception { 7 // TODO 自動生成的方法存根 8 9 String readline = null; 10 String inTemp = null; 11 //String outTemp = null; 12 String turnLine = "\n"; 13 final String client = "Client:"; 14 final String server = "Server:"; 15 16 int port = 4000; 17 byte ipAddressTemp[] = {127, 0, 0, 1}; 18 InetAddress ipAddress = InetAddress.getByAddress(ipAddressTemp); 19 20 //首先直接創建socket,端口號1~1023為系統保存,一般設在1023之外 21 Socket socket = new Socket(ipAddress, port); 22 23 //創建三個流,系統輸入流BufferedReader systemIn,socket輸入流BufferedReader socketIn,socket輸出流PrintWriter socketOut; 24 BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in)); 25 BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 26 PrintWriter socketOut = new PrintWriter(socket.getOutputStream()); 27 28 while(readline != "bye"){ 29 30 System.out.println(client); 31 readline = systemIn.readLine(); 32 //System.out.println(readline); 33 34 socketOut.println(readline); 35 socketOut.flush(); //趕快刷新使Server收到,也可以換成socketOut.println(readline, ture) 36 37 //outTemp = readline; 38 inTemp = socketIn.readLine(); 39 40 //System.out.println(client + outTemp); 41 System.out.println(server + turnLine + inTemp); 42 43 } 44 45 systemIn.close(); 46 socketIn.close(); 47 socketOut.close(); 48 socket.close(); 49 50 } 51 52 }
服務器Server源碼如下:
import java.io.*; import java.net.*; public class Server { public static void main(String[] args) throws Exception { // TODO 自動生成的方法存根 String readline = null; String inTemp = null; //String outTemp = null; String turnLine = "\n"; final String client = "Client:"; final String server = "Server:"; int port = 4000; //byte ipAddressTemp[] = {127, 0, 0, 1}; //InetAddress ipAddress = InetAddress.getByAddress(ipAddressTemp); //首先直接創建serversocket ServerSocket serverSocket = new ServerSocket(port);
//調用服務器的accept()進行阻塞(程序會在這等待),當有申請連接時會打開阻塞並返回一個socket Socket socket = serverSocket.accept(); //創建三個流,系統輸入流BufferedReader systemIn,socket輸入流BufferedReader socketIn,socket輸出流PrintWriter socketOut; BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in)); BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter socketOut = new PrintWriter(socket.getOutputStream()); while(readline != "bye"){ inTemp = socketIn.readLine(); System.out.println(client + turnLine + inTemp); System.out.println(server); readline = systemIn.readLine(); socketOut.println(readline); socketOut.flush(); //趕快刷新使Client收到,也可以換成socketOut.println(readline, ture) //outTemp = readline; //System.out.println(server); } systemIn.close(); socketIn.close(); socketOut.close(); socket.close(); serverSocket.close(); } }
調試結果如下:
調試的時候要先啟動服務器,客戶端查不到服務器就運行不了。
運行效果還是很好的,幸運的是寫完直接就可以運行了,關鍵是思路對,由此我總結出了一個規律,不管要做什么項目,首先要查閱資料,了解並理解其原理,還要思路清晰,這樣子才能保證程序的成功率。還要多查閱java手冊可以知道各種類的構造函數,返回值。提供一個java手冊下載網址http://www.jb51.net/books/128276.html
另外通過socket編程還學會了一個調試的小技巧,就是多顯示器的調試按這個小三角就好了