java中的網絡編程之TCP協議的詳細介紹,以及如何使用,同時我在下面舉2例說明如何搭配IO流進行操作,

1 /* 2 *TCP 3 *建立連接,形成傳輸數據的通道; 4 *在連接中進行大數據量傳輸; 5 *通過三次握手完成連接,是可靠協議; 6 *必須建立連接,效率會稍低 7 */ 8 9 /* 10 * TCP傳輸 11 * Socket和ServerSocket建立客戶端和服務器端建立連接后, 12 * 通過Socket中的IO流進行數據的傳輸關閉socket同樣, 13 * 客戶端與服務器端是兩個獨立的應用程序。 14 */ 15 16 //------------------------------- 17 //下面的是TCP協議的服務器端代碼 18 19 import java.io.IOException; 20 import java.io.InputStream; 21 import java.net.ServerSocket; 22 import java.net.Socket; 23 24 /* 25 * TCP協議接收數據 26 * 1.創建接收端的socket對象 27 * 2.監聽客戶端,返回一個對應的socket對象 28 * 3.獲取輸入流,讀取數據,顯示在控制台 29 * 4.釋放資源 30 */ 31 public class ServerDemo { 32 public static void main(String[] args) throws IOException { 33 // 創建接收端socket對象 34 ServerSocket ss = new ServerSocket(10086); 35 36 // 監聽客戶端,返回一個對應的socket對象 37 // public Socket accept() 偵聽並接受到此套接字的連接。 38 Socket s = ss.accept(); // 阻塞式方法,直到通道建立 39 40 // 獲取輸入流,讀取數據 41 InputStream is = s.getInputStream(); 42 byte[] bys = new byte[1024]; 43 int len = is.read(bys); // 阻塞式方法,直到數據發過來。 44 String ip = s.getInetAddress().getHostAddress(); 45 46 String str = new String(bys, 0, len); 47 System.out.println(str); 48 49 // 釋放資源 50 s.close(); 51 ss.close(); // 這個不應該關閉 52 } 53 } 54 55 //------------------------------- 56 //下面是客戶端TCP協議的代碼 57 import java.io.IOException; 58 import java.io.OutputStream; 59 import java.net.Socket; 60 61 /* 62 *TCP協議發送數據: 63 * 1.創建發送端socket對象 64 * 這一步如果成功,就說明鏈接已經成功了。 65 * 2.獲取輸出流,寫數據 66 * 3.釋放資源 67 * 68 *TCP一些服務器必須先開啟,保證通道簡歷,否則直接報錯。 69 *java.net.ConnectException: Connection refused: connect 70 */ 71 public class ClientDemo { 72 public static void main(String[] args) throws IOException { 73 // 創建發送端socket對象 74 // Socket(String host, int port) 創建一個流套接字並將其連接到指定主機上的指定端口號。 75 Socket socket = new Socket("lpp-PC", 10086); 76 //“lpp-PC”里面的字符串一般使用服務器端的IP地址代替。 77 78 // 獲取輸出流,寫數據 79 OutputStream os = socket.getOutputStream(); 80 os.write("TCP coming~~~".getBytes()); 81 82 // 關閉資源 83 os.close(); 84 } 85 }
1 //================================== 2 //--------------------------------------------------------------- 3 //下面給出一個案例:客戶端從指定文本文件讀取數據,發送到服務器端, 4 //服務器將接收到的數據,再次寫入到一個新的文本文件。數據的寫/出是字節 5 //流 6 7 //首先給出的是客戶端的代碼: 8 import java.io.BufferedReader; 9 import java.io.BufferedWriter; 10 import java.io.FileReader; 11 import java.io.IOException; 12 import java.io.InputStreamReader; 13 import java.io.OutputStreamWriter; 14 import java.net.Socket; 15 16 /* 17 * 客戶端從文本文件中讀取數據,服務器得到數據寫入到文本文件, 18 * 為了在服務器寫完數據后,給客戶端一個反饋,但是直接在通道內額外的添加數據是不行,會導致雙方一直保持等待狀態 19 * 方案 20 * 1: 在客戶端里面額外增加一條語句告訴服務器結束的標志。 21 * 2: 直接使用JDK給出的方法:shutdownOutput();socket提供了一個中止功能,它會通知服務器別等了,我沒有數據過來了。 22 */ 23 24 public class ClientDemo { 25 public static void main(String[] args) throws IOException { 26 // 客戶端socket對象 27 Socket s = new Socket("lpp-PC", 12345); 28 29 // 封裝數據源 30 BufferedReader br = new BufferedReader(new FileReader("a.txt")); 31 32 // 封裝通道內流 33 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter( 34 s.getOutputStream())); 35 36 // 寫入數據 37 String line = null; 38 while ((line = br.readLine()) != null) { 39 bw.write(line); 40 bw.newLine(); 41 bw.flush(); 42 } 43 44 // // 為了告訴服務器寫到這里就可以停止了,額外增加一個標記,自定義一個結束標記 45 // bw.write("over"); 46 // bw.newLine(); 47 // bw.flush(); 48 49 //socket提供了一個中止功能,它會通知服務器別等了,我沒有數據過來了。 50 s.shutdownOutput(); 51 52 // 接受服務器的反饋 53 BufferedReader brClient = new BufferedReader(new InputStreamReader( 54 s.getInputStream())); 55 String str = brClient.readLine(); 56 System.out.println(str); 57 58 // 釋放資源 59 br.close(); 60 s.close(); 61 } 62 } 63 64 65 //------------------------------------------ 66 //下面是服務器端的代碼 67 68 69 import java.io.BufferedReader; 70 import java.io.BufferedWriter; 71 import java.io.FileReader; 72 import java.io.FileWriter; 73 import java.io.IOException; 74 import java.io.InputStreamReader; 75 import java.io.OutputStreamWriter; 76 import java.net.ServerSocket; 77 import java.net.Socket; 78 79 public class ServerDemo { 80 public static void main(String[] args) throws IOException { 81 // 服務端socke對象 82 ServerSocket ss = new ServerSocket(12345); 83 84 // 監聽客戶端,獲取socke對象 85 Socket s = ss.accept(); 86 87 // 封裝目標文件 88 BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt")); 89 90 // 封裝通道中的輸入流 91 BufferedReader br = new BufferedReader(new InputStreamReader( 92 s.getInputStream())); 93 94 // 讀取數據,並將數據寫入文件 95 String line = null; 96 while ((line = br.readLine()) != null) { 97 // if ("over".equals(line)) { 98 // break; 99 // } 100 bw.write(line); 101 bw.newLine(); 102 bw.flush(); 103 } 104 105 // 在文件寫出完畢后,給客戶端一個反饋, 106 BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter( 107 s.getOutputStream())); 108 bwServer.write("數據寫入完畢"); 109 bwServer.newLine(); 110 bwServer.flush(); 111 112 // 釋放資源 113 bw.close(); 114 s.close(); 115 116 } 117 }
//======================================
//下面的這個例子是客戶端讀取的是圖片文件/視頻文件。而服務器會對象通過TCP協議讀取到的數據寫到對應格式的文中去。
1 //先是服務器端的class文件 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.OutputStream; 8 import java.net.ServerSocket; 9 import java.net.Socket; 10 11 public class ServerDemo { 12 public static void main(String[] args) throws IOException { 13 // 服務端socke對象 14 ServerSocket ss = new ServerSocket(23456); 15 16 // 監聽客戶端,獲取socket 17 Socket s = ss.accept(); 18 19 // 封裝通道內流數據 20 BufferedInputStream bis = new BufferedInputStream(s.getInputStream()); 21 22 // 封裝圖標目的地 23 BufferedOutputStream bos = new BufferedOutputStream( 24 new FileOutputStream("lpp.jpg")); 25 26 byte[] bys = new byte[1024]; 27 int len = 0; 28 while ((len = bis.read(bys)) != -1) { 29 bos.write(bys, 0, len); 30 bos.flush(); // 尤其是在通道內部使用時,必須使用flush否則丟包 31 } 32 33 // 給一個反饋 34 OutputStream os = s.getOutputStream(); 35 os.write("圖片上傳成功".getBytes()); 36 37 // 釋放資源 38 bos.close(); 39 s.close(); 40 41 } 42 } 43 44 45 //------------------------------------------------ 46 //下面的是客戶端的class文件 47 48 import java.io.BufferedInputStream; 49 import java.io.BufferedOutputStream; 50 import java.io.File; 51 import java.io.FileInputStream; 52 import java.io.IOException; 53 import java.io.InputStream; 54 import java.io.OutputStream; 55 import java.net.Socket; 56 57 /* 58 * 客戶端讀取一個數據,通過TCP協議發送到服務器 59 */ 60 public class ClientDemo { 61 public static void main(String[] args) throws IOException { 62 // 客戶端socke對象 63 Socket s = new Socket("lll-PC", 23456); 64 65 // 封裝數據源 66 BufferedInputStream bis = new BufferedInputStream(new FileInputStream( 67 "a.jpg")); 68 69 // 封裝通道數據流 70 BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream()); 71 72 byte[] bys = new byte[1024]; 73 int len = 0; 74 while ((len = bis.read(bys)) != -1) { 75 bos.write(bys, 0, len); 76 bos.flush(); //尤其是在通道內部使用時,必須使用flush否則丟包 77 } 78 79 // 讀取反饋,關閉寫入流,並告知服務器端,服務器端的阻塞不再等待向下執行 80 s.shutdownOutput(); 81 82 InputStream is = s.getInputStream(); 83 byte[] buf = new byte[1024]; 84 int len2 = is.read(buf); 85 String clientStr = new String(buf, 0, len2); 86 System.out.println(clientStr); 87 88 // 釋放資源 89 bis.close(); 90 s.close(); 91 92 } 93 }
