Socket网络编程tcp聊天案例(心跳包,多线程,断线重连机制)

31 篇文章 1 订阅
3 篇文章 0 订阅

实现一个聊天的案例,使用多线程和心跳包。当服务器断开的时候,客户端会自动尝试重新连接,当服务器开启的时候,客户端会自动连接

Server服务器类

package Demo3_Chat;

import com.sun.source.tree.Scope;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.spec.ECField;
import java.util.Scanner;

public class Server {
    public static void main(String[] args)  {
        System.out.println("服务器已在运行....");
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            while(true){
                Socket socket = serverSocket.accept();
                new Thread(new Server_listen(socket)).start();
                new Thread(new Server_send(socket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class Server_listen implements Runnable{

    private Socket socket;

    Server_listen(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream is = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is,"UTF-8");
            while(true){
                int len = 0;
                char[] charArr = new char[1024];
                while((len = isr.read(charArr)) != -1){
                    System.out.println(new String(charArr,0,len));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try{
                socket.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }
}

class Server_send implements Runnable{

    private Socket socket;
    Server_send(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        try{
            OutputStream os = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
            Scanner sc = new Scanner(System.in);
            while(true){
                System.out.print("请输入要发送的内容:");
                String str = sc.nextLine();
                osw.write(str);
                osw.flush();
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

Client客户端类

package Demo3_Chat;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    private static Socket socket;
    public static boolean connection_state = false;
    private static OutputStreamWriter osw;

    public static void main(String[] args) {
        while(!connection_state){
            connect();
            try{
                Thread.sleep(3000);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }

    public static void connect(){
        try{
            socket = new Socket("127.0.0.1",8888);
            connection_state = true;
            OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream(),"UTF-8");
            new Thread(new Client_listen(socket)).start();
            new Thread(new Client_send(socket,osw)).start();
            new Thread(new Client_heart(socket,osw)).start();
        }catch (Exception e){
            e.printStackTrace();
            connection_state = false;
        }
    }

    //自动重连机制
    public static void reconnect(){
        while(!connection_state){
            System.out.println("正在尝试重新连接.....");
            connect();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

class Client_listen implements Runnable{

    private Socket socket;
    Client_listen(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        try{
            InputStream is = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is,"UTF-8");
            while(true){
                int len = 0;
                char[] charArr = new char[1024];
                while((len = isr.read(charArr)) != -1){
                    System.out.println(new String(charArr,0,len));
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

class Client_send implements Runnable{
    private Socket socket;
    private OutputStreamWriter osw;
    Client_send(Socket socket,OutputStreamWriter osw){
        this.socket = socket;
        this.osw = osw;
    }

    @Override
    public void run(){
        try{
            Scanner sc = new Scanner(System.in);

            while(true){
                System.out.print("请输入要发送的内容:");
                String str = sc.nextLine();
                osw.write(str);
                osw.flush();
            }
        }catch (Exception e){
            e.printStackTrace();
            try{
                socket.close();
                Client.connection_state = false;
                Client.reconnect();

            }catch (Exception e2){
                e2.printStackTrace();
            }
        }
    }
}

//心跳包机制
class Client_heart implements Runnable{

    private Socket socket;
    private OutputStreamWriter osw;
    Client_heart(Socket socket,OutputStreamWriter osw){
        this.socket = socket;
        this.osw = osw;
    }
    @Override
    public void run() {

        try{
            System.out.println("心跳包线程已启动");

            while(true){
                Thread.sleep(5000);
                osw.write("*****心跳包*****");
                osw.flush();
            }
        }catch (Exception e){
            e.printStackTrace();
            try{
                socket.close();
                Client.connection_state = false;
                Client.reconnect();

            }catch (Exception e2){
                e2.printStackTrace();
            }
        }

    }
}

断线重新连接部分代码

//自动重连机制
    public static void reconnect(){
        while(!connection_state){
            System.out.println("正在尝试重新连接.....");
            connect();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

心跳包类

//心跳包机制
class Client_heart implements Runnable{

    private Socket socket;
    private OutputStreamWriter osw;
    Client_heart(Socket socket,OutputStreamWriter osw){
        this.socket = socket;
        this.osw = osw;
    }
    @Override
    public void run() {

        try{
            System.out.println("心跳包线程已启动");

            while(true){
                Thread.sleep(5000);
                osw.write("*****心跳包*****");
                osw.flush();
            }
        }catch (Exception e){
            e.printStackTrace();
            try{
                socket.close();
                Client.connection_state = false;
                Client.reconnect();

            }catch (Exception e2){
                e2.printStackTrace();
            }
        }

    }
}

心跳包实现截图
这里把心跳包输出出来是为了方便查看心跳包是否构建成功
在这里插入图片描述

在这里插入图片描述

断线重连实现截图

正常状态下
在这里插入图片描述
在这里插入图片描述
当服务器关闭后
在这里插入图片描述
在这里插入图片描述

当服务器重启
在这里插入图片描述
重新启动服务器后,服务器和客户端又可以继续进行聊天了,客户端会一直等待服务器的开启。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

兴奋の大公猴

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

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

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

打赏作者

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

抵扣说明:

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

余额充值