JAVA語言基礎-網絡編程

26.01_網絡編程(網絡編程概述)(瞭解)

  • A:計算機網絡
    • 是指將地理位置不一樣的具備獨立功能的多臺計算機及其外部設備,經過通訊線路鏈接起來,在網絡操做系統,網絡管理軟件及網絡通訊協議的管理和協調下,實現資源共享和信息傳遞的計算機系統。
  • B:網絡編程
    • 就是用來實現網絡互連的不一樣計算機上運行的程序間能夠進行數據交換。

26.02_網絡編程(網絡編程三要素之IP概述)(掌握)

  • 每一個設備在網絡中的惟一標識
  • 每臺網絡終端在網絡中都有一個獨立的地址,咱們在網絡中傳輸數據就是使用這個地址。
  • ipconfig:查看本機IP192.168.12.42
  • ping:測試鏈接192.168.40.62
  • 本地迴路地址:127.0.0.1 255.255.255.255是廣播地址
  • IPv4:4個字節組成,4個0-255。大概42億,30億都在北美,亞洲4億。2011年初已經用盡。
  • IPv6:8組,每組4個16進制數。
  • 1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f
  • 1a2b::aaaa:0000:0000:0000:aabb:1f2f
  • 1a2b:0000:aaaa::aabb:1f2f
  • 1a2b:0000:aaaa::0000:aabb:1f2f
  • 1a2b:0000:aaaa:0000::aabb:1f2f

26.03_網絡編程(網絡編程三要素之端口號概述)(掌握)

  • 每一個程序在設備上的惟一標識
  • 每一個網絡程序都須要綁定一個端口號,傳輸數據的時候除了肯定發到哪臺機器上,還要明確發到哪一個程序。
  • 端口號範圍從0-65535
  • 編寫網絡應用就須要綁定一個端口號,儘可能使用1024以上的,1024如下的基本上都被系統程序佔用了。
  • 經常使用端口
    • mysql: 3306
    • oracle: 1521
    • web: 80
    • tomcat: 8080
    • QQ: 4000
    • feiQ: 2425

26.04_網絡編程(網絡編程三要素協議)(掌握)

  • 爲計算機網絡中進行數據交換而創建的規則、標準或約定的集合。
  • UDP
    • 面向無鏈接,數據不安全,速度快。不區分客戶端與服務端。
  • TCP   * 面向鏈接(三次握手),數據安全,速度略低。分爲客戶端和服務端。
    • 三次握手: 客戶端先向服務端發起請求, 服務端響應請求, 傳輸數據
    • 四次揮手:???

26.05_網絡編程(Socket通訊原理圖解)(瞭解)

  • A:Socket套接字概述:
    • 網絡上具備惟一標識的IP地址和端口號組合在一塊兒才能構成惟一能識別的標識符套接字。
    • 通訊的兩端都有Socket。
    • 網絡通訊其實就是Socket間的通訊。
    • 數據在兩個Socket間經過IO流傳輸。
    • Socket在應用程序中建立,經過一種綁定機制與驅動程序創建關係,告訴本身所對應的IP和port。
  • B:Receive   

package com.heima.socket;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class Demo1_Receive {

	/**
	 ** 2.接收Receive
	 * 建立DatagramSocket, 指定端口號
	 * 建立DatagramPacket, 指定數組, 長度
	 * 使用DatagramSocket接收DatagramPacket
	 * 關閉DatagramSocket
	 * 從DatagramPacket中獲取數據
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		DatagramSocket socket = new DatagramSocket(6666);		//建立Socket至關於建立碼頭
		DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//建立Packet至關於建立集裝箱
		socket.receive(packet);									//接貨,接收數據
		
		byte[] arr = packet.getData();							//獲取數據
		int len = packet.getLength();							//獲取有效的字節個數
		System.out.println(new String(arr,0,len));
		socket.close();
	}

}
package com.heima.socket;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class Demo2_Receive {

	/**
	 ** 2.接收Receive
	 * 建立DatagramSocket, 指定端口號
	 * 建立DatagramPacket, 指定數組, 長度
	 * 使用DatagramSocket接收DatagramPacket
	 * 關閉DatagramSocket
	 * 從DatagramPacket中獲取數據
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		DatagramSocket socket = new DatagramSocket(6666);		//建立Socket至關於建立碼頭
		DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//建立Packet至關於建立集裝箱
		
		while(true) {
			socket.receive(packet);									//接貨,接收數據
			
			byte[] arr = packet.getData();							//獲取數據
			int len = packet.getLength();							//獲取有效的字節個數
			String ip = packet.getAddress().getHostAddress();		//獲取ip地址
			int port = packet.getPort();							//獲取端口號
			System.out.println(ip + ":" + port + ":" + new String(arr,0,len));
		}
	}

}
  • Send   

package com.heima.socket;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Demo2_Send {

	/**
	 * * 1.發送Send
	 * 建立DatagramSocket, 隨機端口號
	 * 建立DatagramPacket, 指定數據, 長度, 地址, 端口
	 * 使用DatagramSocket發送DatagramPacket
	 * 關閉DatagramSocket
	 * @throws SocketException 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);						//建立鍵盤錄入對象
		DatagramSocket socket = new DatagramSocket();				//建立Socket至關於建立碼頭
		
		while(true) {
			String line = sc.nextLine();							//獲取鍵盤錄入的字符串
			if("quit".equals(line)) {
				break;
			}
			DatagramPacket packet = 								//建立Packet至關於集裝箱
					new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
			socket.send(packet);									//發貨,將數據發出去
		}
		socket.close();												//關閉碼頭
	}

}
  • MoreThread

package com.heima.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Demo3_MoreThread {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new Receive().start();
		
		new Send().start();
	}

}

class Receive extends Thread {
	public void run() {
		try {
			DatagramSocket socket = new DatagramSocket(6666);		//建立Socket至關於建立碼頭
			DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//建立Packet至關於建立集裝箱
			
			while(true) {
				socket.receive(packet);									//接貨,接收數據
				
				byte[] arr = packet.getData();							//獲取數據
				int len = packet.getLength();							//獲取有效的字節個數
				String ip = packet.getAddress().getHostAddress();		//獲取ip地址
				int port = packet.getPort();							//獲取端口號
				System.out.println(ip + ":" + port + ":" + new String(arr,0,len));
			}
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	}
}

class Send extends Thread {
	public void run() {
		try {
			Scanner sc = new Scanner(System.in);						//建立鍵盤錄入對象
			DatagramSocket socket = new DatagramSocket();				//建立Socket至關於建立碼頭
			
			while(true) {
				String line = sc.nextLine();							//獲取鍵盤錄入的字符串
				if("quit".equals(line)) {
					break;
				}
				DatagramPacket packet = 								//建立Packet至關於集裝箱
						new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
				socket.send(packet);									//發貨,將數據發出去
			}
			socket.close();
		}  catch (IOException e) {
			
			e.printStackTrace();
		}		
	}
}
  • GUIChat    

package com.heima.socket;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo4_GUIChat extends Frame {

	private TextField tf;
	private Button send;
	private Button log;
	private Button clear;
	private Button shake;
	private TextArea viewText;
	private TextArea sendText;
	private DatagramSocket socket;
	private BufferedWriter bw;
	/**
	 * @param args
	 * GUI聊天
	 */
	public Demo4_GUIChat() {
		init();
		southPanel();
		centerPanel();
		event();
	}

	public void event() {
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				try {
					socket.close();
					bw.close();
				} catch (IOException e1) {
					
					e1.printStackTrace();
				}
				System.exit(0);
			}
		});
		
		send.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					send();
				} catch (IOException e1) {
					
					e1.printStackTrace();
				}
			}

		});
		
		log.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					logFile();
				} catch (IOException e1) {
					
					e1.printStackTrace();
				}
			}

		});
		
		clear.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				viewText.setText("");
			}
		});
		
		shake.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					send(new byte[]{-1},tf.getText());
				} catch (IOException e1) {
					
					e1.printStackTrace();
				}
			}

		});
		
		sendText.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				//if(e.getKeyCode() == KeyEvent.VK_ENTER && e.isControlDown()) {	//isControlDown ctrl是否被按下
				if(e.getKeyCode() == KeyEvent.VK_ENTER) {
					try {
						send();
					} catch (IOException e1) {
						
						e1.printStackTrace();
					}
				}
			}
		});
	}
	

	private void shake() {
		int x = this.getLocation().x;							//獲取橫座標位置
		int y = this.getLocation().y;							//獲取縱座標位置
		
		for(int i = 0; i < 20; i++) {
			try {
				this.setLocation(x + 20, y + 20);
				Thread.sleep(20);
				this.setLocation(x + 20, y - 20);
				Thread.sleep(20);
				this.setLocation(x - 20, y + 20);
				Thread.sleep(20);
				this.setLocation(x - 20, y - 20);
				Thread.sleep(20);
				this.setLocation(x, y);
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
		}
	}
	
	private void logFile() throws IOException {
		bw.flush();									//刷新緩衝區
		FileInputStream fis = new FileInputStream("config.txt");
		ByteArrayOutputStream baos = new ByteArrayOutputStream();	//在內存中建立緩衝區
		
		int len;
		byte[] arr = new byte[8192];
		while((len = fis.read(arr)) != -1) {
			baos.write(arr, 0, len);
		}
		
		String str = baos.toString();				//將內存中的內容轉換成了字符串
		viewText.setText(str);
		
		fis.close();
	}
	
	private void send(byte[] arr, String ip) throws IOException {
		DatagramPacket packet = 
				new DatagramPacket(arr, arr.length, InetAddress.getByName(ip), 9999);
		socket.send(packet);						//發送數據
	}
	
	private void send() throws IOException {
		String message = sendText.getText();		//獲取發送區域的內容
		String ip = tf.getText();					//獲取ip地址;
		ip = ip.trim().length() == 0 ? "255.255.255.255" : ip;
		
		send(message.getBytes(),ip);
		
		String time = getCurrentTime();				//獲取當前時間
		String str = time + " 我對:" + (ip.equals("255.255.255.255") ? "全部人" : ip) + "說\r\n" + message + "\r\n\r\n";	//alt + shift + l 抽取局部變量
		viewText.append(str);						//將信息添加到顯示區域中
		bw.write(str);								//將信息寫到數據庫中
		sendText.setText("");
		
		
	}
	
	private String getCurrentTime() {
		Date d = new Date();						//建立當前日期對象
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		return sdf.format(d);						//將時間格式化
	}

	public void centerPanel() {
		Panel center = new Panel();					//建立中間的Panel
		viewText = new TextArea();
		sendText = new TextArea(5,1);
		center.setLayout(new BorderLayout());		//設置爲邊界佈局管理器
		center.add(sendText,BorderLayout.SOUTH);	//發送的文本區域放在南邊
		center.add(viewText,BorderLayout.CENTER);	//顯示區域放在中間
		viewText.setEditable(false);				//設置不能夠編輯
		viewText.setBackground(Color.WHITE);		//設置背景顏色
		sendText.setFont(new Font("xxx", Font.PLAIN, 15));
		viewText.setFont(new Font("xxx", Font.PLAIN, 15));
		this.add(center,BorderLayout.CENTER);
	}

	public void southPanel() {
		Panel south = new Panel();					//建立南邊的Panel
		tf = new TextField(15);
		tf.setText("127.0.0.1");
		send = new Button("發 送");
		log = new Button("記 錄");
		clear = new Button("清 屏");
		shake = new Button("震 動");
		south.add(tf);
		south.add(send);
		south.add(log);
		south.add(clear);
		south.add(shake);
		this.add(south,BorderLayout.SOUTH);			//將Panel放在Frame的南邊
	}

	public void init() {
		this.setLocation(500, 50);
		this.setSize(400, 600);
		new Receive().start();
		try {
			socket = new DatagramSocket();
			bw = new BufferedWriter(new FileWriter("config.txt",true));	//須要在尾部追加
		} catch (Exception e) {
			
			e.printStackTrace();
		}
		this.setVisible(true);
	}
	private class Receive extends Thread {			//接收和發送須要同時執行,因此定義成多線程的
		public void run() {
			try {
				DatagramSocket socket = new DatagramSocket(9999);
				DatagramPacket packet = new DatagramPacket(new byte[8192], 8192);
				
				while(true) {
					socket.receive(packet);				//接收信息
					byte[] arr = packet.getData();		//獲取字節數據
					int len = packet.getLength();		//獲取有效的字節數據
					if(arr[0] == -1 && len == 1) {		//若是發過來的數組第一個存儲的值是-1,而且數組長度是1
						shake();						//調用震動方法
						continue;						//終止本次循環,繼續下次循環,由於震動後不須要執行下面的代碼
					}
					String message = new String(arr,0,len);	//轉換成字符串
					
					String time = getCurrentTime();		//獲取當前時間
					String ip = packet.getAddress().getHostAddress();	//獲取ip地址
					String str = time + " " + ip + " 對我說:\r\n" + message + "\r\n\r\n";
					viewText.append(str);
					bw.write(str);
				}
			} catch (Exception e) {
				
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		new Demo4_GUIChat();
	}

}

26.06_網絡編程(UDP傳輸)(瞭解)

  • 1.發送Send
    • 建立DatagramSocket, 隨機端口號
    • 建立DatagramPacket, 指定數據, 長度, 地址, 端口
    • 使用DatagramSocket發送DatagramPacket
    • 關閉DatagramSocket
  • 2.接收Receive
    • 建立DatagramSocket, 指定端口號
    • 建立DatagramPacket, 指定數組, 長度
    • 使用DatagramSocket接收DatagramPacket
    • 關閉DatagramSocket
    • 從DatagramPacket中獲取數據
  • 3.接收方獲取ip和端口號
    • String ip = packet.getAddress().getHostAddress();
    • int port = packet.getPort();

26.07_網絡編程(UDP傳輸優化)

  • 接收端Receive
  • DatagramSocket socket = new DatagramSocket(6666);                       //建立socket至關於建立碼頭
    DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);       //建立packet至關於建立集裝箱
    
    while(true) {
        socket.receive(packet);                                             //接收貨物
        byte[] arr = packet.getData();
        int len = packet.getLength();
        String ip = packet.getAddress().getHostAddress();
        System.out.println(ip + ":" + new String(arr,0,len));
    }
  • 發送端Sendjava

    DatagramSocket socket = new DatagramSocket();       //建立socket至關於建立碼頭
    Scanner sc = new Scanner(System.in);
    
    while(true) {
        String str = sc.nextLine();
        if("quit".equals(str))
            break;
        DatagramPacket packet =                             //建立packet至關於建立集裝箱
                new DatagramPacket(str.getBytes(), str.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
        socket.send(packet);            //發貨
    }
    socket.close();

26.08_網絡編程(UDP傳輸多線程)

  • A發送和接收在一個窗口完成mysql

    public class Demo3_MoreThread {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            new Receive().start();
    
            new Send().start();
        }
    
    }
    
    class Receive extends Thread {
        public void run() {
            try {
                DatagramSocket socket = new DatagramSocket(6666);                   //建立socket至關於建立碼頭
                DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);   //建立packet至關於建立集裝箱
    
                while(true) {
                    socket.receive(packet);                                             //接收貨物
                    byte[] arr = packet.getData();
                    int len = packet.getLength();
                    String ip = packet.getAddress().getHostAddress();
                    System.out.println(ip + ":" + new String(arr,0,len));
                }
            } catch (IOException e) {
    
                e.printStackTrace();
            }
        }
    }
    
    class Send extends Thread {
        public void run() {
            try {
                DatagramSocket socket = new DatagramSocket();       //建立socket至關於建立碼頭
                Scanner sc = new Scanner(System.in);
    
                while(true) {
                    String str = sc.nextLine();
                    if("quit".equals(str))
                        break;
                    DatagramPacket packet =                             //建立packet至關於建立集裝箱
                            new DatagramPacket(str.getBytes(), str.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
                    socket.send(packet);            //發貨
                }
                socket.close();
            }  catch (IOException e) {
    
                e.printStackTrace();
            }
        }
    }

26.09_網絡編程(UDP聊天圖形化界面)

26.10_網絡編程(UDP聊天發送功能)

26.11_網絡編程(UDP聊天記錄功能)

26.12_網絡編程(UDP聊天清屏功能)

26.13_網絡編程(UDP聊天震動功能)

26.14_網絡編程(UDP聊天快捷鍵和代碼優化)

26.15_網絡編程(UDP聊天生成jar文件)

26.16_網絡編程(TCP協議)(掌握)

  • 1.客戶端
    • 建立Socket鏈接服務端(指定ip地址,端口號)經過ip地址找對應的服務器
    • 調用Socket的getInputStream()和getOutputStream()方法獲取和服務端相連的IO流
    • 輸入流能夠讀取服務端輸出流寫出的數據
    • 輸出流能夠寫出數據到服務端的輸入流
  • 2.服務端
    • 建立ServerSocket(須要指定端口號)
    • 調用ServerSocket的accept()方法接收一個客戶端請求,獲得一個Socket
    • 調用Socket的getInputStream()和getOutputStream()方法獲取和客戶端相連的IO流
    • 輸入流能夠讀取客戶端輸出流寫出的數據
    • 輸出流能夠寫出數據到客戶端的輸入流
  • Demo1

    Client

package com.heima.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Demo1_Client {

	/**
	 * * 1.客戶端
		* 建立Socket鏈接服務端(指定ip地址,端口號)經過ip地址找對應的服務器
		* 調用Socket的getInputStream()和getOutputStream()方法獲取和服務端相連的IO流
		* 輸入流能夠讀取服務端輸出流寫出的數據
		* 輸出流能夠寫出數據到服務端的輸入流
	 * @throws IOException 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("127.0.0.1", 12345);
		
		InputStream is = socket.getInputStream();			//獲取客戶端輸入流
		OutputStream os = socket.getOutputStream();			//獲取客戶端的輸出流
		
		byte[] arr = new byte[1024];
		int len = is.read(arr);								//讀取服務器發過來的數據
		System.out.println(new String(arr,0,len));       	//將數據轉換成字符串並打印
		
		os.write("學習挖掘機哪家強?".getBytes());					//客戶端向服務器寫數據
		
		socket.close();
	}

}

Server

package com.heima.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo1_Server {

	/**
	 * * 2.服務端
	* 建立ServerSocket(須要指定端口號)
	* 調用ServerSocket的accept()方法接收一個客戶端請求,獲得一個Socket
	* 調用Socket的getInputStream()和getOutputStream()方法獲取和客戶端相連的IO流
	* 輸入流能夠讀取客戶端輸出流寫出的數據
	* 輸出流能夠寫出數據到客戶端的輸入流
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(12345);
		
		Socket socket = server.accept();						//接受客戶端的請求
		InputStream is = socket.getInputStream();			//獲取客戶端輸入流
		OutputStream os = socket.getOutputStream();			//獲取客戶端的輸出流
		
		os.write("百度一下你就知道".getBytes());					//服務器向客戶端寫出數據
		
		byte[] arr = new byte[1024];
		int len = is.read(arr);								//讀取客戶端發過來的數據
		System.out.println(new String(arr,0,len));       	//將數據轉換成字符串並打印
		
		socket.close();
	}

}
  • Demo2

Client

package com.heima.tcp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Demo2_Client {

	/**
	 * * 1.客戶端
		* 建立Socket鏈接服務端(指定ip地址,端口號)經過ip地址找對應的服務器
		* 調用Socket的getInputStream()和getOutputStream()方法獲取和服務端相連的IO流
		* 輸入流能夠讀取服務端輸出流寫出的數據
		* 輸出流能夠寫出數據到服務端的輸入流
	 * @throws IOException 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("127.0.0.1", 12345);
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));		//將字節流包裝成了字符流
		PrintStream ps = new PrintStream(socket.getOutputStream());					//PrintStream中有寫出換行的方法
		
		System.out.println(br.readLine());
		ps.println("我想報名黑馬程序員");
		System.out.println(br.readLine());
		ps.println("大哭!!!能不能給次機會");
		
		socket.close();
	}

}

Server

package com.heima.tcp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo2_Server {

	/**
	 * * 2.服務端
	* 建立ServerSocket(須要指定端口號)
	* 調用ServerSocket的accept()方法接收一個客戶端請求,獲得一個Socket
	* 調用Socket的getInputStream()和getOutputStream()方法獲取和客戶端相連的IO流
	* 輸入流能夠讀取客戶端輸出流寫出的數據
	* 輸出流能夠寫出數據到客戶端的輸入流
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		ServerSocket server = new ServerSocket(12345);
		
		while(true) {
			final Socket socket = server.accept();						//接受客戶端的請求
			new Thread() {
				public void run() {
					try {
						BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));		//將字節流包裝成了字符流
						PrintStream ps = new PrintStream(socket.getOutputStream());					//PrintStream中有寫出換行的方法
						
						ps.println("歡迎諮詢黑馬程序員");
						System.out.println(br.readLine());
						ps.println("很差意思,爆滿了");
						System.out.println(br.readLine());
						socket.close();
					} catch (IOException e) {
						
						e.printStackTrace();
					}
				}
			}.start();
		}
	}

	public static void demo1() throws IOException {
		ServerSocket server = new ServerSocket(12345);
		
		Socket socket = server.accept();						//接受客戶端的請求
		
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));		//將字節流包裝成了字符流
		PrintStream ps = new PrintStream(socket.getOutputStream());					//PrintStream中有寫出換行的方法
		
		ps.println("歡迎諮詢黑馬程序員");
		System.out.println(br.readLine());
		ps.println("很差意思,爆滿了");
		System.out.println(br.readLine());
		socket.close();
	}

}

26.17_網絡編程(TCP協議代碼優化)

  • 客戶端程序員

    Socket socket = new Socket("127.0.0.1", 9999);      //建立Socket指定ip地址和端口號
    InputStream is = socket.getInputStream();           //獲取輸入流
    OutputStream os = socket.getOutputStream();         //獲取輸出流
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    PrintStream ps = new PrintStream(os);
    
    System.out.println(br.readLine());
    ps.println("我想報名就業班");
    System.out.println(br.readLine());
    ps.println("爺不學了");
    socket.close();
  • 服務端web

    ServerSocket server = new ServerSocket(9999);   //建立服務器
    Socket socket = server.accept();                //接受客戶端的請求
    InputStream is = socket.getInputStream();       //獲取輸入流
    OutputStream os = socket.getOutputStream();     //獲取輸出流
    
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    PrintStream ps = new PrintStream(os);
    
    ps.println("歡迎諮詢傳智播客");
    System.out.println(br.readLine());
    ps.println("報滿了,請報下一期吧");
    System.out.println(br.readLine());
    server.close();
    socket.close();

26.18_網絡編程(服務端是多線程的)(掌握)

ServerSocket server = new ServerSocket(9999);   //建立服務器
    while(true) {
        final Socket socket = server.accept();              //接受客戶端的請求
        new Thread() {
            public void run() {
                try {
                    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    PrintStream ps = new PrintStream(socket.getOutputStream());
                    ps.println("歡迎諮詢傳智播客");
                    System.out.println(br.readLine());
                    ps.println("報滿了,請報下一期吧");
                    System.out.println(br.readLine());
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}

26.19_網絡編程(練習)

  • 客戶端向服務器寫字符串(鍵盤錄入),服務器(多線程)將字符串反轉後寫回,客戶端再次讀取到是反轉後的字符串

    Client

package com.heima.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Test1_Client {

	/**
	 * 客戶端向服務器寫字符串(鍵盤錄入),服務器(多線程)將字符串反轉後寫回,客戶端再次讀取到是反轉後的字符串
	 * @throws IOException 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws UnknownHostException, IOException {
		Scanner sc = new Scanner(System.in);				//建立鍵盤錄入對象
		Socket socket = new Socket("127.0.0.1", 54321);		//建立客戶端,指定ip地址和端口號
		
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));	//獲取輸入流
		PrintStream ps = new PrintStream(socket.getOutputStream());//獲取輸出流
		
		ps.println(sc.nextLine());							//將字符串寫到服務器去
		System.out.println(br.readLine()); 					//將反轉後的結果讀出來
		
		socket.close();
	}

}

Server

package com.heima.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Test1_Server {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(54321);
		System.out.println("服務器啓動,綁定54321端口");
		
		while(true) {
			final Socket socket = server.accept();					//接受客戶端的請求
			
			new Thread() {											//開啓一條線程
				public void run() {
					try {
						BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));	//獲取輸入流
						PrintStream ps = new PrintStream(socket.getOutputStream());//獲取輸出流
						
						String line = br.readLine();				//將客戶端寫過來的數據讀取出來
						line = new StringBuilder(line).reverse().toString();	//鏈式編程
						ps.println(line);							//反轉後寫回去
						
						socket.close();
					} catch (IOException e) {						
						
						e.printStackTrace();
					}
				}
			}.start();
		}
	}

}

26.20_網絡編程(練習)

  • 客戶端向服務器上傳文件

    Client

package com.heima.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Test2_UpdateClient {

	/**
	 * @param args
	 * @throws IOException 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws UnknownHostException, IOException {
		// 1.提示輸入要上傳的文件路徑, 驗證路徑是否存在以及是不是文件夾
		File file = getFile();
		// 2.發送文件名到服務端
		Socket socket = new Socket("127.0.0.1", 12345);
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		PrintStream ps = new PrintStream(socket.getOutputStream());
		ps.println(file.getName());
		// 6.接收結果, 若是存在給予提示, 程序直接退出
		String result = br.readLine();						//讀取存在後不存在的結果
		if("存在".equals(result)) {
			System.out.println("您上傳的文件已經存在,請不要重複上傳");
			socket.close();
			return;
		}
		// 7.若是不存在, 定義FileInputStream讀取文件, 寫出到網絡
		FileInputStream fis = new FileInputStream(file);
		byte[] arr = new byte[8192];
		int len;
		
		while((len = fis.read(arr)) != -1) {
			ps.write(arr, 0, len);
		}
		
		fis.close();
		socket.close();
	}

	private static File getFile() {
		Scanner sc = new Scanner(System.in);				//建立鍵盤錄入對象
		System.out.println("請輸入一個文件路徑:");
		
		while(true) {
			String line = sc.nextLine();
			File file = new File(line);
			
			if(!file.exists()) {
				System.out.println("您錄入的文件路徑不存在,請從新錄入:");
			}else if(file.isDirectory()) {
				System.out.println("您錄入的是文件夾路徑,請輸入一個文件路徑:");
			}else {
				return file;
			}
		}
	}
}

Server

package com.heima.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Test2_UpdateServer {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//3,創建多線程的服務器
		ServerSocket server = new ServerSocket(12345);
		System.out.println("服務器啓動,綁定12345端口號");
		
		//4.讀取文件名
		while(true) {
			final Socket socket = server.accept();					//接受請求
			new Thread() {
				public void run() {
					try {
						InputStream is = socket.getInputStream();
						BufferedReader br = new BufferedReader(new InputStreamReader(is));
						PrintStream ps = new PrintStream(socket.getOutputStream());
						String fileName = br.readLine();
						
						//5.判斷文件是否存在, 將結果發回客戶端
						File dir = new File("update");
						dir.mkdir();								//建立文件夾
						File file = new File(dir,fileName);			//封裝成File對象
						
						if(file.exists()) {							//若是服務器已經存在這個文件
							ps.println("存在");						//將存在寫給客戶端
							socket.close();							//關閉socket
							return;
						}else {
							ps.println("不存在");
						}
						
						//8.定義FileOutputStream, 從網絡讀取數據, 存儲到本地
						FileOutputStream fos = new FileOutputStream(file);
						byte[] arr = new byte[8192];
						int len;
						
						while((len = is.read(arr)) != -1) {
							fos.write(arr, 0, len);
						}
						
						fos.close();
						socket.close();
					} catch (IOException e) {
						
						e.printStackTrace();
					}
				}
			}.start();
		}
		
		
		
	}
}
相關文章
相關標籤/搜索