TCP传输

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();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lemon20120331

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值