TCP协议
TCP协议就好像是打电话,必须有一个客户端和一个服务器,需要两方接通才可以实现通信
连接时需要三次握手
断开时需要四次挥手
三次握手
第一次握手:建立连接时,客户端发送 syn 包(syn=j)到服务器,并进入 SYN_SEND 状态,等待服务器确认;
第二次握手:服务器收到 syn 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;
第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。
四次挥手
由于 TCP 连接是全双工的,因此每个方向都必须单独进行关闭。
这好比,我们打电话(全双工),正常的情况下(出于礼貌),通话的双方都要说再见后才能挂电话,保证通信双方都把话说完了才挂电话。
那TCP 的四次握手,是为了保证通信双方都关闭了连接,具体过程如下:
实现TCP聊天
关闭连接时需要在关闭前进行判断在关闭
下面为了省事所以是直接关闭的
客户端
/**
* @author Zhm
* @date 2020/11/8 21:17
* 客户端
**/
public class TCPClientDemo01 {
public static void main(String[] args) throws Exception {
// 指定服务器地址
InetAddress serverIP = InetAddress.getByName("127.0.0.1");
// 指定服务器端口
Integer port = 9090;
// 创建连接器
Socket socket = new Socket(serverIP,port);
// 创建一个输出流
OutputStream ops = socket.getOutputStream();
// 输出东西
ops.write("你好".getBytes());
// 关闭连接
socket.close();
}
}
服务器
/**
* @author Zhm
* @date 2020/11/8 21:46
* 服务器
**/
public class TPCServerDemo01 {
public static void main(String[] args) throws Exception {
// 指定端口号
ServerSocket serverSocket = new ServerSocket(9090);
// 创建连接器
Socket socket = serverSocket.accept();
// 创建输入流 接收客户端发送的数据
InputStream is = socket.getInputStream();
// 为防止乱码.创建一个管道流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// 进行输出
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
// 打印数据
System.out.println(bos.toString());
// 关闭连接 这步没有的话会报一个连接重置的错误
socket.close();
}
}
TCP文件传输
客户端
/**
* @author Zhm
* @date 2020/11/8 22:13
* 客户端传输文件
**/
public class TCPClientDemo02 {
public static void main(String[] args) throws Exception {
// 指定地址,我是测试所以用的本地的
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
// 指定端口
int port = 9999;
// 创建socket连接
Socket socket = new Socket(inetAddress, port);
// 创建输入流
OutputStream os = socket.getOutputStream();
// 读取文件
FileInputStream fis = new FileInputStream(new File("D:\\111.jpg"));
// 输出文件
byte[] bytes = new byte[1024];
int len;
while ((len = fis.read(bytes)) != -1) {
os.write(bytes,0,len);
}
// 关闭连接, 正规的话需要在关闭前进行判断在关闭
fis.close();
os.close();
socket.close();
}
}
服务器
/**
* @author Zhm
* @date 2020/11/8 22:22
* 文件接收服务器
**/
public class TCPServerDemo02 {
public static void main(String[] args) throws IOException {
// 指定端口
ServerSocket serverSocket = new ServerSocket(9999);
// 创建socket连接
Socket socket = serverSocket.accept();
// 创建输入流
InputStream is = socket.getInputStream();
// 创建输出流
FileOutputStream fos = new FileOutputStream(new File("D:\\test\\1.jpg"));
// 开始输出
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1) {
fos.write(bytes,0,len);
}
// 关闭连接
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}