27-JAVA中的網絡編程(socket通信)

 

###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。

###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));
        }

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();
	}

}


* 發送端Send

        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();

package com.heima.socket;

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

public class Demo1_Send {

	/**
	 * * 1.發送Send
	 * 創建DatagramSocket, 隨機端口號
	 * 創建DatagramPacket, 指定數據, 長度, 地址, 端口
	 * 使用DatagramSocket發送DatagramPacket
	 * 關閉DatagramSocket
	 * @throws SocketException 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws Exception {
		String str = "what are you 弄啥呢?";
		DatagramSocket socket = new DatagramSocket();				//創建Socket相當於創建碼頭
		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發送和接收在一個窗口完成

        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();
                }
            }
        }

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();
		}		
	}
}


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

###26.10_網絡編程(UDP聊天發送功能)
    
        
###26.11_網絡編程(UDP聊天記錄功能)
    
    
###26.12_網絡編程(UDP聊天清屏功能)


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


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

package 網絡編程;

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 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 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.PINK );		//設置背景顏色
		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 GUIchat();
	}

}



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

###26.16_網絡編程(TCP協議)(掌握)
* 1.客戶端
    * 創建Socket連接服務端(指定ip地址,端口號)通過ip地址找對應的服務器
    * 調用Socket的getInputStream()和getOutputStream()方法獲取和服務端相連的IO流
    * 輸入流可以讀取服務端輸出流寫出的數據
    * 輸出流可以寫出數據到服務端的輸入流
* 2.服務端
    * 創建ServerSocket(需要指定端口號)
    * 調用ServerSocket的accept()方法接收一個客戶端請求,得到一個Socket
    * 調用Socket的getInputStream()和getOutputStream()方法獲取和客戶端相連的IO流
    * 輸入流可以讀取客戶端輸出流寫出的數據
    * 輸出流可以寫出數據到客戶端的輸入流

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();
	}

}

 

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();
	}

}

###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();

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();
	}

}


* 服務端

        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();
        }
    }

 

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.19_網絡編程(練習)
* 客戶端向服務器寫字符串(鍵盤錄入),服務器(多線程)將字符串反轉後寫回,客戶端再次讀取到是反轉後的字符串

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();
	}

}
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_網絡編程(練習)
* 客戶端向服務器上傳文件

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;
			}
		}
	}
}
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();
		}
		
		
		
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章