第84節:Java中的網絡編程(中)

標題圖

第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

結語

  • 下面我將繼續對 其餘知識 深刻講解 ,有興趣能夠繼續關注
  • 小禮物走一走 or 點贊
相關文章
相關標籤/搜索