一.TCP协议
TCP传输控制协议 (Transmission Control Protocol)。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。
-
三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
-
第一次握手,客户端向服务器端发出连接请求,等待服务器确认。
-
第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。
-
第三次握手,客户端再次向服务器端发送确认信息,确认连接。
-
由于TCP协议的面向连接特性,它可以保证传输数据的安全性,所以是一个被广泛采用的协议,例如在下载文件时,如果数据接收不完整,将会导致文件数据丢失而不能被打开,因此,下载文件时必须采用TCP协议.
二.TCP协议编程用到的类
TCP协议中的类也主要分为客户端的类和服务器端的类,具体代码如下:
//获得一个客户端的Socket对象,用于向服务器发送连接请求
Socket client = new Socket("localhost", 8888);
//输出流 用于向服务器输出数据
OutputStream os = client.getOutputStream();
//输入流 用于接收服务器返回的数据
InputStream is = client.getInputStream();
//禁用Socket的此输出流
client.shutdownOutput();
//输出流的写方法,输出数据
os.write("Hello TCP".getBytes());
/**********************************************************/
//ServerSocket对象 设定一个端口号,用于等待客户端的连接
ServerSocket ss = new ServerSocket(8888);
//当客户端发来连接请求时,调用此方法,创建一个Socket对象
Socket accept = ss.accept();
InputStream is = accept.getInputStream();
byte[] b = new byte[1024];
//通过输入流读取客户端传来的数据
int len = is.read(b);
String string = new String(b, 0, len);
三.TCP通信过程
第一步,服务器端 启动,创建ServerSocket对象,等待连接
第二步,客户端 启动,创建Socket对象,请求连接
第三步,服务器端 接收连接,调用accept对象,返回一个Socket对象(如果客户端没有发送请求,那么这个方法一直是阻塞的)
第四步,客户端 获取OutputStream,向服务器端写数据
第五步,服务器端 获取InputStream,读取客户端发送的数据
第六步,服务器端 获取OutputStream,向客户端写数据
第七步,客户端 获取InputStream,读取服务器端发送的数据
第八步,断开连接,释放资源。
/*客户端*/
public class TcpClient {
public static void main(String[] args) throws Exception {
//1.定义一个Socket,要指定IP地址和端口号
Socket client = new Socket("localhost", 8888);
//2.获得一个输出流向服务器端写数据
OutputStream os = client.getOutputStream();
//2.1将要传输的数据封装在一个字节数组中
byte[] bytes = "Hello TcpTest".getBytes();
os.write(bytes);
/******************************************************/
//3.获得一个输入流读取服务器端发送的数据
InputStream is = client.getInputStream();
//3.1定义一个字节数组接收数据
byte[] info = new byte[1024];
int len = is.read(info);
String res = new String(info, 0, len);
//3.2打印数据
System.out.println(res);
//4.关闭连接 释放资源
is.close();
os.close();
client.close();
}
}
/*服务器端*/
public class TcpServer {
public static void main(String[] args) throws Exception {
//1.创建一个ServerSocket对象,要指定端口号
ServerSocket server = new ServerSocket(8888);
//2.调用accept()方法,等待客户端连接,如果客户端不发送连接,则一直阻塞
Socket accept = server.accept();
//3.获得输入流,读取客户端发送来的数据
InputStream is = accept.getInputStream();
//3.1定义一个字节数组来接收数据
byte[] info = new byte[1024];
int len = is.read(info);
String res1 = new String(info, 0, len);
//打印接收来的数据
System.out.println(res1);
/***************************************************/
//4.获得输出流,向客户端发送数据
OutputStream os = accept.getOutputStream();
//4.1用一个字节数组封装要发送的数据
byte[] reInfo = "Hello World".getBytes();
os.write(reInfo);
//5.断开连接 释放资源
os.close();
is.close();
accept.close();
}
}
四.TCP协议的文件上传案例
/*客户端*/
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 static void main(String[] args) throws IOException {
System.out.println("服务器 启动..... ");
// 1. 创建服务端ServerSocket
ServerSocket serverSocket = new ServerSocket(6666);
// 2. 循环接收,建立连接
Socket accept = serverSocket.accept();
/*
*3. socket对象进行读写操作
*/
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();
}
}
}