第84節:Java中的網絡編程(中)java
實現客戶端和服務端的通訊:web
客戶端須要的操做,建立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(); } }
服務端:app
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(); } } }
上傳圖片socket
客戶端:
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