JavaDay21 tcp三次握手、tcp和udp协议的区别、交互图片的练习

1. 简述TCP的三次握手。

TCP的三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
(1)第一次握手,客户端向服务器端发出连接请求,等待服务器确认;
(2)第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求;
(3)第三次握手,客户端再次向服务器端发送确认信息,确认连接。
完成上述的三次握手后,客户端和服务器端的连接就已经建立了,每次连接的创建都需要经过“三次握手”的过程。

2. TCP协议和UDP协议的区别。

(1)UDP(用户数据报协议):
(1)UDP是无连接通信协议,在数据传输时,数据的发送和接收端不建立连接,也不能保证对方能接收成功。
(2)当一台计算机向另外一台计算机发送数据时(UDP),发送端不会确认接收端是否存在,就会直接发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
(3)由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输,传输重要数据时不建议使用UDP协议,因为它不能保证数据传输的完整性。

(2)TCP(传输控制协议):
(1)TCP协议是面向连接的通信协议。
(2)传输数据之前,在发送端和接收端建立连接,然后再传输数据,它提供了两台计算机之间可靠的、无差错的数据传输。
(3)在TCP连接中,将计算机明确划分为客户端与服务器端,并且由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”的过程。

(3)TCP和UDP的区别:

  1. TCP提供面向连接的传输,通信前要先建立连接(三次握手机制); UDP提供无连接的传输,通信前不需要建立连接。
  2. TCP提供可靠的传输(有序,无差错,不丢失,不重复);UDP提供不可靠的传输。
  3. TCP面向字节流的传输,因此它能将信息分割成组,并在接收端将其重组; UDP是面向数据报的传输,没有分组开销。
  4. TCP提供拥塞控制和流量控制机制; UDP不提供拥塞控制和流量控制机制。

3. 客户端需求:把一个图片文件发送到服务端并读取回馈信息。服务端需求:接收客户端发送过来的图片数据。进行存储后,回馈一个“上传成功”字样。

  1. 图片可以完成交互,但控制台会抛出Socket异常:
//服务器端:
package com.briup.day23;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * @author chouhan
 * 1.服务端需求:接收客户端发送过来的图片数据。进行存储后,回馈一个“上传成功”字样。
 */
public class TestServer {
	public static void main(String[] args) throws IOException{
		ServerSocket server=new ServerSocket(8899);
		Socket socket=server.accept();
		BufferedInputStream bi=new BufferedInputStream(socket.getInputStream());
		BufferedOutputStream bo=new BufferedOutputStream(new FileOutputStream("C:\\Users\\Starg\\Desktop\\hzw.png"));
		byte[] b=new byte[1024];
		int len=-1;
		while((len=bi.read(b))!=-1) {
			bo.write(b,0,len);
		}
		bo.flush();
		OutputStream out=socket.getOutputStream();
		out.write("上传成功".getBytes());
		bo.close();
		socket.close();
	}
}
//客户端:
package com.briup.day23;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
/**
 * @author chouhan
 * 2.客户端需求:把一个图片文件发送到服务端并读取回馈信息。
 */
public class TestClient {
	public static void main(String[] args) throws IOException {
		Socket socket=new Socket("127.0.0.1",8899);
		BufferedInputStream bi=new BufferedInputStream
				(new FileInputStream("C:\\Users\\Starg\\Desktop\\onepiece.png"));
		BufferedOutputStream bo=
				new BufferedOutputStream(socket.getOutputStream());
		byte[] b=new byte[1024];
		int len=-1;
		while((len=bi.read(b))!=-1) {
			bo.write(b,0,len);
		}
		bo.flush();
		socket.shutdownInput();
		System.out.println("上传结束");
		InputStream in=socket.getInputStream();
		byte[] b2=new byte[1024];
		int len2=in.read(b2);
		String data=new String(b2,0,len2);
		System.out.println(data);
		socket.close();
		bi.close();
	}
}
  1. 完成图片交互且客户端收到服务器的反馈信息:
package com.briup.day23;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * @author chouhan
 * 1.服务端需求:接收客户端发送过来的图片数据。进行存储后,回馈一个“上传成功”字样。
 */
public class TestServer {
	public static void main(String[] args) throws IOException{
		ServerSocket server=new ServerSocket(8899);
		//1.同意连接
		Socket socket=server.accept();
		//2.把网络读取的文件保存到字节缓冲输入流
		BufferedInputStream bi=new BufferedInputStream(socket.getInputStream());
		//3.用字节缓冲输出流把网络输出流传到指定文件
		BufferedOutputStream bo=new BufferedOutputStream(
				new FileOutputStream("C:/Users/Starg/Desktop/hzw.png"));
		//4.一点点把字节缓冲输入流读取到的文件传到字节缓冲输出流
		int len=-1;
		while((len=bi.read())!=-1) {
			bo.write(len);
		}
		//5.读完字节缓冲输出流后刷新
		bo.flush();
		System.out.println("图片已完成接收");
		//6.把网络输出流的信息传到字节打印输出流中
		PrintStream ps=new PrintStream(socket.getOutputStream());
		//7.给客户端提供一个反馈
		ps.println("上传成功");
	}
}
package com.briup.day23;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
 * @author chouhan
 * 2.客户端需求:把一个图片文件发送到服务端并读取回馈信息。
 */
public class TestClient {
	public static void main(String[] args) throws IOException {
		//1.请求连接
		Socket socket=new Socket("127.0.0.1",8899);
		System.out.println("开始上传");
		//2.把本地文件读到缓冲输入流中
		BufferedInputStream bi=new BufferedInputStream
				(new FileInputStream("C:/Users/Starg/Desktop/onepiece.png"));
		//3.用字节缓冲输出流把文件写到网络文件
		BufferedOutputStream bo=
				new BufferedOutputStream(socket.getOutputStream());
		//4.把字节缓冲输入流的文件一点点读到缓冲输出流
		int len=-1;
		while((len=bi.read())!=-1) {
			bo.write(len);
		}
		//5.读完文件刷新
		bo.flush();
		//6.把网络输出流关闭
		socket.shutdownOutput();
		//7.用缓冲字符输入流读服务器端传过来的“上传成功”
		BufferedReader br=new BufferedReader(
				new InputStreamReader(socket.getInputStream()));
		//8.打印上传成功
		System.out.println(br.readLine());
	}
}

总结:
(1)读取完文件后要刷新;
(2)客户端的网络传输完成后,socket要通过shutdownOutput()方法把输出流关闭;
(3)文件的读取和写入的文件路径必须存在且允许访问;
(4)缓冲流传递文件提高读写效率。

你可能感兴趣的:(Java基础的作业整理,tcp/ip,java)