自学Java——day_21 网络编程

1.基本常识

1.1 软件结构

  • C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。
  • B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。

1.2 网络通信三要素

  • 协议
  • IP地址
  • 端口号(0-65535)

1.3 常见网络通信协议

自学Java——day_21 网络编程_第1张图片

2.TCP通信程序

TCP通信能实现两台计算机之间的数据交互,通信的两端,要严格区分为客户端(Client)与服务端(Server)。
两端通信时步骤:

  1. 服务端程序,需要事先启动,等待客户端的连接。
  2. 客户端主动连接服务器端,连接成功才能通信。服务端不可以主动连接客户端。
	在Java中,提供了两个类用于实现TCP通信程序: 
	1. 客户端: java.net.Socket 类表示。创建 Socket 对象,向服务端发出
	连接请求,服务端响应请求,两者建立连接开始通信。 
	2. 服务端: java.net.ServerSocket 类表示。创建 ServerSocket 对象,
	相当于开启一个服务,并等待客户端的连接。

2.1 Socket类

Socket 类:该类实现客户端套接字,套接字指的是两台设备之间通讯的端点。

2.1.1 构造方法

  • public Socket(String host, int port) :创建套接字对象并将其连接到指定主机上的指定端口号。

如果指定的host是null ,则相当于指定地址为环回地址。

环回地址(127.x.x.x) 是本机环回地址(Loopback Address),主要用于网络软件测试以及本地机进程间通信,无论什么程序,一旦使用环回地址发送数据,立即返回,不进行任何网络传输。

2.1.2 成员方法

  • public InputStream getInputStream() : 返回此套接字的输入流。 如果此Scoket具有相关联的通道,则生成的InputStream 的所有操作也关联该通道。 关闭生成的InputStream也将关闭相关的Socket。
  • public OutputStream getOutputStream() : 返回此套接字的输出流。 如果此Scoket具有相关联的通道,则生成的OutputStream 的所有操作也关联该通道。 关闭生成的OutputStream也将关闭相关的Socket。
  • public void close() :关闭此套接字。 一旦一个socket被关闭,它不可再使用。 关闭此socket也将关闭相关的InputStream和OutputStream 。
  • public void shutdownOutput() : 禁用此套接字的输出流。 任何先前写出的数据将被发送,随后终止输出流。

2.2 ServerSocket类

ServerSocket 类:这个类实现了服务器套接字,该对象等待通过网络的请求。

2.2.1 构造方法

  • public ServerSocket(int port) :使用该构造方法在创建ServerSocket对象时,就可以将其绑定到一个指 定的端口号上,参数port就是端口号。

2.2.2 成员方法

public Socket accept() :侦听并接受连接,返回一个新的Socket对象,用于和客户端实现通信。该方法会一直阻塞直到建立连接。

2.3 TCP通信分析图解

自学Java——day_21 网络编程_第2张图片

  1. 【服务端】启动,创建ServerSocket对象,等待连接。
    Socket client = new Socket(“127.0.0.1”, 6666);
    ServerSocket server = new ServerSocket(6666);
  2. 【客户端】启动,创建Socket对象,请求连接。
  3. 【服务端】接收连接,调用accept方法,并返回一个Socket对象。
  4. 【客户端】Socket对象,获取OutputStream,向服务端写出数据。
  5. 【服务端】Scoket对象,获取InputStream,读取客户端发送的数据。

到此,客户端向服务端发送数据成功。

然后,服务端向客户端回写数据。

  1. 【服务端】Socket对象,获取OutputStream,向客户端回写数据。
  2. 【客户端】Scoket对象,获取InputStream,解析回写数据。
  3. 【客户端】释放资源,断开连接。

3.综合案例

3.1 文件上传

  1. 【客户端】输入流,从硬盘读取文件数据到程序中。
  2. 【客户端】输出流,写出文件数据到服务端。
  3. 【服务端】输入流,读取文件数据到服务端程序。
  4. 【服务端】输出流,写出文件数据到服务器硬盘中。

客户端:

public class FileUpload_Client {
    public static void main(String[] args) throws IOException {
		// 1.创建流对象         
		// 1.1 创建输入流,读取本地文件         
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.jpg"));         
		// 1.2 创建输出流,写到服务端         
		Socket socket = new Socket("localhost", 6666);         
		BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());           
		//2.写出数据.         
		byte[] b  = new byte[1024 * 8 ];         
		int len ;         
		while (( len  = bis.read(b))!=1) {             
			bos.write(b, 0, len);         
		}        
		// 关闭输出流,通知服务端,写出数据完毕            
		socket.shutdownOutput();         
		System.out.println("文件发送完毕");         
		// 3. =====解析回写============         
		InputStream in = socket.getInputStream();         
		byte[] back = new byte[20];         
		in.read(back);         
		System.out.println(new String(back));         
		in.close();         
		// 4.释放资源         
		socket.close();         
		bis.close();     
	} 
}

服务端

public class FileUpload_Server {     
	public static void main(String[] args) throws IOException {         
		System.out.println("服务器 启动.....  ");         
		// 1. 创建服务端ServerSocket         
		ServerSocket serverSocket = new ServerSocket(6666);         
		// 2. 循环接收,建立连接         
		while (true) {             
			Socket accept = serverSocket.accept();            
			/*3. socket对象交给子线程处理,进行读写操作                   	
			Runnable接口中,只有一个run方法,使用lambda表达式简化格式*/             
			new Thread(()> {                 
				try (                     
					//3.1 获取输入流对象                     
					BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());                     
					//3.2 创建输出流对象, 保存到本地 .                     
					FileOutputStream fis = new FileOutputStream(System.currentTimeMillis() +  ".jpg");                     
					BufferedOutputStream bos = new BufferedOutputStream(fis);) {                     
					// 3.3 读写数据                     
					byte[] b = new byte[1024 * 8];                     
					int len;                     
					while ((len = bis.read(b)) !=1) {                         
						bos.write(b, 0, len);                     
					}                       
					// 4.=======信息回写========              
					System.out.println("back ........");                     
					OutputStream out = accept.getOutputStream();                     
					out.write("上传成功".getBytes());                     
					out.close();                     
					//5. 关闭 资源                     
					bos.close();                     
					bis.close();                     
					accept.close();                     
					System.out.println("文件上传已保存");                 
				} catch (IOException e) {                     
					e.printStackTrace(); 
				}             
			}).start();         
		}     
	} 
}

3.2 模拟B\S服务器

模拟网站服务器,使用浏览器访问自己编写的服务端程序,查看网页效果。

public class ServerDemo {     
	public static void main(String[] args) throws IOException {         
		ServerSocket server = new ServerSocket(8888);         
		while(true){             
			Socket socket = server.accept();             
			new Thread(new Web(socket)).start();         
		}     
	}     
	static class Web implements Runnable{         
		private Socket socket;           
		public Web(Socket socket){             
			this.socket=socket;         
		}           
		public void run() {             
			try{                 
				//转换流,读取浏览器请求第一行                 
				BufferedReader readWb = new                         BufferedReader(new InputStreamReader(socket.getInputStream()));                 
				String requst = readWb.readLine();                 
				//取出请求资源的路径                 
				String[] strArr = requst.split(" ");                 
				System.out.println(Arrays.toString(strArr));                 
				String path = strArr[1].substring(1);                 
				System.out.println(path);                   
				FileInputStream fis = new FileInputStream(path);                 
				System.out.println(fis);                 
				byte[] bytes= new byte[1024];                 
				int len = 0 ;                 
				//向浏览器 回写数据                 
				OutputStream out = socket.getOutputStream();                 
				out.write("HTTP/1.1 200 OK\r\n".getBytes());                 
				out.write("Content‐Type:text/html\r\n".getBytes());                 
				out.write("\r\n".getBytes());                 
				while((len = fis.read(bytes))!=1){                     
					out.write(bytes,0,len);                 
				}                 
				fis.close();                 
				out.close();                 
				readWb.close();                 
				socket.close();             
			}catch(Exception ex){               
			
			}         
		}     
	}   
}

你可能感兴趣的:(java基础知识,Java网络编程,软件结构,网络通信三要素,常见网络协议,TCP通信程序案例)