第84節:Java中的網路程式設計(中)

標題圖
第84節:Java中的網路程式設計(中)
實現客戶端和服務端的通訊:
客戶端需要的操作,建立socket,明確地址和埠,進行鍵盤錄入,獲取需要的資料,然後將錄入的資料傳送給服務端,為socket輸出流,然後進行讀取服務端傳送回來的大寫資料,為socket讀取流,最後進行客戶端顯示器的顯示,進行讀寫操作,關閉資源。
網路程式設計TCP客戶端
package com.dashucoding.tcp3; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class TransClient { public static void main(String[] args) throws IOException { // 客戶端 // 建立socket 明確地址和埠 Socket s = new Socket("192.168.1.151",10005); // 鍵盤錄入 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); // 網路, socket輸出流 //OutputStream out = s.getOutputStream(); // 傳的是字元資料, 轉換,提高效率 //BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(out)); // 列印流,既能接收字元又能接收位元組 PrintWriter out = new PrintWriter(s.getOutputStream()); // 讀取流,讀取服務端發來的資料 //InputStream in = s.getInputStream(); BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); // 顯示資料,使用輸出語句 // 頻繁讀寫,讀鍵盤 String line = null; while((line=bufr.readLine()) != null) { if("over".equals(line)) { break; } // 讀取鍵盤的資料傳送到服務端 out.println(line); // 讀取服務端返回的資料 String upperText = bufIn.readLine(); System.out.println(upperText); } // 關閉資源 s.close(); } }
對於服務端,要建立一個服務端的socket,然後明確埠,要讀取客戶端傳送過來的資料,要讀取socket輸入流,接著使用socket輸出流,將資料傳送給客戶端,進行讀寫操作,關閉資源。
網路程式設計TCP服務端
package com.dashucoding.tcp3; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class TransServer { public static void main(String[] args) throws IOException { System.out.println("服務端執行。。。"); // 服務端: // 建立服務端的socket,明確埠 ServerSocket ss = new ServerSocket(10005); while (true) { // 獲取客戶端物件 Socket s = ss.accept(); // 列印ip地址 System.out.println(s.getInetAddress().getHostAddress()+"...connected"); // socket輸入流,讀取客戶端發過來的資料 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); // socket輸出流,將資料傳送給客戶端 //PrintWriter out = new PrintWriter(s.getOutputStream()); PrintWriter out = new PrintWriter(s.getOutputStream(), true); // 頻繁的讀寫操作 String line = null; while ((line = bufIn.readLine()) != null) { // 如果客戶端傳送過來的是over if ("over".equals(line)) { break; } // 客戶端的資料 System.out.println(line); // 字母轉大寫 out.println(line.toUpperCase()); // 都在緩衝區中,重新整理 //out.flush(); } // 關閉客戶端 s.close(); } } }
package com.dashucoding.tcp3; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class TransClient { public static void main(String[] args) throws IOException { System.out.println("客戶端執行。。。"); // 客戶端 // 建立socket 明確地址和埠 Socket s = new Socket("192.168.2.151",10005); // 鍵盤錄入 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); // 網路, socket輸出流 //OutputStream out = s.getOutputStream(); // 傳的是字元資料, 轉換,提高效率 //BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(out)); // 列印流,既能接收字元又能接收位元組 //PrintWriter out = new PrintWriter(s.getOutputStream()); PrintWriter out = new PrintWriter(s.getOutputStream(), true); // 讀取流,讀取服務端發來的資料 //InputStream in = s.getInputStream(); BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); // 顯示資料,使用輸出語句 // 頻繁讀寫,讀鍵盤 String line = null; // 都一行,有行終止符才返回 while((line=bufr.readLine()) != null) { // 讀取鍵盤的資料傳送到服務端 //out.print(line+"\r\n"); out.println(line); // 刷資料,都在緩衝區中 //out.flush(); if("over".equals(line)) { break; } // 讀取服務端返回的資料 String upperText = bufIn.readLine(); System.out.println(upperText); } // 關閉資源 s.close(); } }
上傳檔案
void shutdownInput() 此套接字的輸入流置於“流的末尾” void shutdownOutput() 禁用此套接字的輸出流 String toString() 將此套接字轉換為String.
客戶端:
package com.dashucoding.net.uploadtext; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class UploadTextClient { public static void main(String[] args) throws UnknownHostException, IOException { System.out.println("上傳檔案客戶端執行。。。"); // 客戶端 // 建立socket 明確地址和埠 Socket s = new Socket("192.168.43.126", 10006); // 讀取文字檔案 BufferedReader bufr = new BufferedReader(new FileReader("tempfile\\client.txt")); // 將資料傳送給服務端 PrintWriter out = new PrintWriter(s.getOutputStream(), true); // 顯示資料,使用輸出語句 // 頻繁讀寫,讀鍵盤 String line = null; // 都一行,有行終止符才返回true while ((line = bufr.readLine()) != null) { out.println(line); } // 給服務端傳送一個結束標記,條約標記 //out.println("over"); s.shutdownOutput(); // 向服務端傳送了結束標記 // 讀取流,讀取服務端發來的資料 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String info = bufIn.readLine(); System.out.println(info); // 關閉資源 bufr.close(); s.close(); } }
服務端:
package com.dashucoding.net.uploadtext; import java.io.BufferedReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class UploadTextServer { public static void main(String[] args) throws IOException { System.out.println("上傳文字服務端執行。。。"); // 服務端: // 建立服務端的socket,明確埠 ServerSocket ss = new ServerSocket(10006); while (true) { // 獲取客戶端物件 Socket s = ss.accept(); System.out.println(s.getInetAddress().getHostAddress() + "...connected"); // socket輸入流,讀取客戶端發過來的資料 BufferedReader bufIn = new BufferedReader(new InputStreamReader( s.getInputStream())); // socket輸出流,目的是檔案 PrintWriter pw = new PrintWriter(new FileWriter("tempfile\\server.txt"), true); // 頻繁的讀寫操作 String line = null; while ((line = bufIn.readLine()) != null) { if("over".equals(line)) { break; } pw.println(line); } // 發回給客戶端,上傳成功 PrintWriter out = new PrintWriter(s.getOutputStream(),true); out.println("上傳成功"); // 關閉客戶端 s.close(); } } }
上傳圖片
客戶端:
package com.dashucoding.net.uploadpic; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class UploadPicClient { public static void main(String[] args) throws IOException { System.out.println("上傳圖片客戶端執行。。。"); // 上傳圖片 // 建立socket Socket s = new Socket("192.168.43.126",10007); // 讀取圖片,圖片路徑 File picFile = new File("tempfile\\001.jpg"); FileInputStream fis = new FileInputStream(picFile); // socket 輸出流 OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf)) != -1) { out.write(buf,0,len); } // 告訴伺服器端圖片資料傳送完畢,不要等著讀了。 s.shutdownOutput(); // 讀取上傳成功 InputStream in = s.getInputStream(); byte[] bufIn = new byte[1024]; int lenIn = in.read(bufIn); System.out.println(new String(bufIn, 0, lenIn)); // 關閉 fis.close(); s.close(); } }
服務端:
package com.dashucoding.net.uploadpic; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import org.omg.CORBA_2_3.portable.OutputStream; public class UploadPicServer { public static void main(String[] args) throws IOException { System.out.println("上傳圖片服務端執行。。。"); // 建立serversocket ServerSocket ss = new ServerSocket(10007); while (true) { // 實現上傳多回 // 獲取客戶端 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+"...connected"); // 讀取圖片資料 InputStream in = s.getInputStream(); // 寫圖片資料到檔案 File picFile = new File("tempfile\\server.jpg"); // 儲存圖片 FileOutputStream fos = new FileOutputStream(picFile); byte[] buf = new byte[1024]; int len = 0; while ((len = in.read(buf)) != -1) { fos.write(buf, 0, len); } // 給客戶端返回一個回饋資訊 java.io.OutputStream out = s.getOutputStream(); out.write("上傳成功".getBytes()); // 關閉資源 fos.close(); s.close(); } } }
如何解決圖片重名的問題:
package com.dashucoding.net.uploadpic; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class UploadPicClient { public static void main(String[] args) throws IOException { System.out.println("上傳圖片客戶端執行。。。"); // 上傳圖片 // 建立socket Socket s = new Socket("192.168",10007); // 讀取圖片,圖片路徑 File picFile = new File("tempfile\\001.jpg"); FileInputStream fis = new FileInputStream(picFile); // socket 輸出流 OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf)) != -1) { out.write(buf,0,len); } // 告訴伺服器端圖片資料傳送完畢,不要等著讀了。 s.shutdownOutput(); // 讀取上傳成功 InputStream in = s.getInputStream(); byte[] bufIn = new byte[1024]; int lenIn = in.read(bufIn); System.out.println(new String(bufIn, 0, lenIn)); // 關閉 fis.close(); s.close(); } }
package com.dashucoding.net.uploadpic; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import org.omg.CORBA_2_3.portable.OutputStream; public class UploadPicServer { public static void main(String[] args) throws IOException { System.out.println("上傳圖片服務端執行。。。"); // 建立serversocket ServerSocket ss = new ServerSocket(10007); while (true) { // 實現上傳多回 // 獲取客戶端 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+"...connected"); // 讀取圖片資料 InputStream in = s.getInputStream(); // 寫圖片資料到檔案 // 建立目錄 File dir = new File("e:\\uploadpic"); // 如果不存在就建立目錄 if(!dir.exists()) { dir.mkdir(); } // 給檔案編號 // 加計數器 int count = 1; // 防止第二次為0 File picFile = new File(dir, ip + "("+count+").jpg"); //if(picFile.exists()) { while(picFile.exists()) { count++; picFile = new File(dir, ip + "("+count+").jpg"); } FileOutputStream fos = new FileOutputStream(picFile); //File picFile = new File("tempfile\\" + ip + ".jpg"); //File picFile = new File("tempfile\\server.jpg"); // 儲存圖片 byte[] buf = new byte[1024]; int len = 0; while ((len = in.read(buf)) != -1) { fos.write(buf, 0, len); } // 給客戶端返回一個回饋資訊 java.io.OutputStream out = s.getOutputStream(); out.write("上傳成功".getBytes()); // 關閉資源 fos.close(); s.close(); } } }
解決上傳併發的問題

結構
package com.dashucoding.net.uploadpic; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class UploadPicClient { public static void main(String[] args) throws IOException { System.out.println("上傳圖片客戶端執行。。。"); // 上傳圖片 // 建立socket Socket s = new Socket("",10007); // 讀取圖片,圖片路徑 File picFile = new File("tempfile\\001.jpg"); FileInputStream fis = new FileInputStream(picFile); // socket 輸出流 OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf)) != -1) { out.write(buf,0,len); } // 告訴伺服器端圖片資料傳送完畢,不要等著讀了。 s.shutdownOutput(); // 讀取上傳成功 InputStream in = s.getInputStream(); byte[] bufIn = new byte[1024]; int lenIn = in.read(bufIn); System.out.println(new String(bufIn, 0, lenIn)); // 關閉 fis.close(); s.close(); } }
package com.dashucoding.net.uploadpic; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import org.omg.CORBA_2_3.portable.OutputStream; public class UploadPicServer { public static void main(String[] args) throws IOException { System.out.println("上傳圖片服務端執行。。。"); // 建立serversocket ServerSocket ss = new ServerSocket(10007); while (true) { // 實現上傳多回 // 獲取客戶端 Socket s = ss.accept(); new Thread(new UploadPic(s)).start(); } } }
package com.dashucoding.net.uploadpic; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; // 建立任務 // 執行緒完成任務後,會自動結束 public class UploadPic implements Runnable { private Socket s; // 建立建構函式 public UploadPic(Socket s) { this.s = s; } @Override public void run() { try { // 主執行緒負債接收客戶端,其它執行緒負責接收資料 String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + "...connected"); // 讀取圖片資料 InputStream in = s.getInputStream(); // 寫圖片資料到檔案 // 建立目錄 File dir = new File("e:\\uploadpic"); // 如果不存在就建立目錄 if (!dir.exists()) { dir.mkdir(); } // 給檔案編號 // 加計數器 int count = 1; // 防止第二次為0 File picFile = new File(dir, ip + "(" + count + ").jpg"); //if(picFile.exists()) { while (picFile.exists()) { count++; picFile = new File(dir, ip + "(" + count + ").jpg"); } FileOutputStream fos = new FileOutputStream(picFile); // 開始迴圈進行讀寫操作 // 一個執行緒,不能處理併發的資料 byte[] buf = new byte[1024]; int len = 0; while ((len = in.read(buf)) != -1) { fos.write(buf, 0, len); } // 給客戶端返回一個回饋資訊 java.io.OutputStream out = s.getOutputStream(); out.write("上傳成功".getBytes()); // 關閉資源 fos.close(); s.close(); } catch (IOException e) { e.printStackTrace(); } } }
客戶端:瀏覽器,服務端:Tomcat
埠號, \con\server.xml
:

效果
瀏覽器傳送HTTP請求
GET / HTTP / 1.1 Accept: Accept-Language: Accept-Encoding: User-Agent: Host: Connection:
請求行,協議,應用層協議,超文字傳輸協議,請求方式,訪問資源的路徑,http的協議版本,

效果
package com.dashucoding.net.myserver; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class MyBrowser { public static void main(String[] args) throws UnknownHostException, IOException { // 瀏覽器傳送http訊息 Socket s = new Socket("",8080); // 把資訊傳送給服務端 PrintWriter out=new PrintWriter(s.getOutputStream(),true); out.println(""); out.println();//空行 // 讀取服務端的資料 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; String text = new String(buf,0,len); System.out.print(text); s.close(); } }
傳送和http協議相同的資訊,收到了Tomcat伺服器返回的資料。

版本

外掛
package com.dashucoding.net.myserver; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; public class MyBrowserGui extends JFrame { private JPanel contentPane; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { MyBrowserGui frame = new MyBrowserGui(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public MyBrowserGui() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 300); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); contentPane.setLayout(new BorderLayout(0, 0)); setContentPane(contentPane); } }

下載外掛
url的描述
java.net 類 url java.lang.object java.net.url 所有已實現的介面: serializable public final class url extends object implements serializable url 表示一個統一的資源定位符,用於指向網際網路"資源"的指標。
// 構造方法 url (string spec): 根據string表示形式建立url物件 url (string protocol, string host, int port, string file) 根據指定protocol,host,port號和file建立url物件
package com.dashucoding.net.url; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class URLDemo { public static void main(String[] args) throws IOException { String str_url = "http://"; //將url地址封裝成物件。 URL url = new URL(str_url); //System.out.println("getProtocol:"+url.getProtocol()); //System.out.println("getHost:"+url.getHost()); //System.out.println("getPort:"+url.getPort()); //System.out.println("getPath:"+url.getPath()); //System.out.println("getFile:"+url.getFile()); //System.out.println("getQuery:"+url.getQuery()); //獲取指定資源的連線物件,封裝了socket。 URLConnection conn = url.openConnection(); //System.out.println(conn); InputStream in = conn.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String text = new String(buf,0,len); System.out.println(text); } }
openConnection public URLConnection openConnection() throws IOException 返回一個URLConnection物件,它表示到url所引用的遠端物件的連線
urlconnection

圖片
package com.dashucoding.net.url; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class URLDemo { public static void main(String[] args) throws IOException { String str_url = "http://"; // 將url地址封裝成物件。 URL url = new URL(str_url); //System.out.println("getProtocol:"+url.getProtocol()); //System.out.println("getHost:"+url.getHost()); //System.out.println("getPort:"+url.getPort()); //System.out.println("getPath:"+url.getPath()); //System.out.println("getFile:"+url.getFile()); //System.out.println("getQuery:"+url.getQuery()); // 獲取指定資源的連線物件,封裝了socket。 URLConnection conn = url.openConnection(); //System.out.println(conn); InputStream in = conn.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String text = new String(buf, 0, len); System.out.println(text); } }
網路程式設計中HTTP版本的區別
http1.0請求一次連線就斷開了,一次連線只能有一次請求,http1.1一次連線多次請求。
URL用於解析url地址,URLConnection用於獲取url的連線。
常見的網路架構:cs和bs
client / server 客戶端和服務端,維護麻煩 browser / server 只需要服務端,只要系統內建瀏覽器 所有的運算在服務端,簡單易用
結言
好了,歡迎在留言區留言,與大家分享你的經驗和心得。
感謝你學習今天的內容,如果你覺得這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友,感謝。
達叔小生:往後餘生,唯獨有你
You and me, we are family !
90後帥氣小夥,良好的開發習慣;獨立思考的能力;主動並且善於溝通
簡書部落格: 達叔小生
https://www.jianshu.com/u/c785ece603d1結語
- 下面我將繼續對 其他知識 深入講解 ,有興趣可以繼續關注
- 小禮物走一走 or 點贊