1. 简述TCP的三次握手。
TCP的三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。 (1)第一次握手,客户端向服务器端发出连接请求,等待服务器确认; (2)第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求; (3)第三次握手,客户端再次向服务器端发送确认信息,确认连接。 完成上述的三次握手后,客户端和服务器端的连接就已经建立了,每次连接的创建都需要经过“三次握手”的过程。
2. TCP协议和UDP协议的区别。
UDP(用户数据报协议): (1)UDP是无连接通信协议,在数据传输时,数据的发送和接收端不建立连接,也不能保证对方能接收成功。 (2)当一台计算机向另外一台计算机发送数据时(UDP),发送端不会确认接收端是否存在,就会直接发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。 (3)由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输,传输重要数据时不建议使用UDP协议,因为它不能保证数据传输的完整性。
TCP(传输控制协议): (1)TCP协议是面向连接的通信协议。 (2)传输数据之前,在发送端和接收端建立连接,然后再传输数据,它提供了两台计算机之间可靠的、无差错的数据传输。 (3)在TCP连接中,将计算机明确划分为客户端与服务器端,并且由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”的过程。
区别:
- TCP提供面向连接的传输,通信前要先建立连接(三次握手机制); UDP提供无连接的传输,通信前不需要建立连接。
- TCP提供可靠的传输(有序,无差错,不丢失,不重复);UDP提供不可靠的传输。
- TCP面向字节流的传输,因此它能将信息分割成组,并在接收端将其重组; UDP是面向数据报的传输,没有分组开销。
- TCP提供拥塞控制和流量控制机制; UDP不提供拥塞控制和流量控制机制。
3. 客户端需求:把一个图片文件发送到服务端并读取回馈信息。服务端需求:接收客户端发送过来的图片数据。进行存储后,回馈一个“上传成功”字样。
- 图片可以完成交互,但控制台会抛出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;
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;
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();
}
}
- 完成图片交互且客户端收到服务器的反馈信息:
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;
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"));
int len=-1;
while((len=bi.read())!=-1) {
bo.write(len);
}
bo.flush();
System.out.println("图片已完成接收");
PrintStream ps=new PrintStream(socket.getOutputStream());
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;
public class TestClient {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("127.0.0.1",8899);
System.out.println("开始上传");
BufferedInputStream bi=new BufferedInputStream
(new FileInputStream("C:/Users/Starg/Desktop/onepiece.png"));
BufferedOutputStream bo=
new BufferedOutputStream(socket.getOutputStream());
int len=-1;
while((len=bi.read())!=-1) {
bo.write(len);
}
bo.flush();
socket.shutdownOutput();
BufferedReader br=new BufferedReader(
new InputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());
}
}
总结: (1)读取完文件后要刷新; (2)客户端的网络传输完成后,socket要通过shutdownOutput()方法把输出流关闭; (3)文件的读取和写入的文件路径必须存在且允许访问; (4)缓冲流传递文件提高读写效率。
|