java BIO tcp服务端向客户端消息群发代码教程实战

Posted 洛阳泰山

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java BIO tcp服务端向客户端消息群发代码教程实战相关的知识,希望对你有一定的参考价值。

前言 

   项目需要和第三方厂商的服务需要用TCP协议通讯,考虑到彼此双方可能都会有断网重连、宕机重启的情况,需要保证 发生上述情况后,服务之间能够自动实现重新通信。研究测试之后整理如下代码实现。因为发现客户端重启后,对于服务端来说原来的客户端和服务端进程进程已经关闭,启动又和服务端新开了一个进程。所以实现原理就可以通过服务端向客户端群发实现,断开重新连接通讯。

代码 

tcp服务端代码




import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class HttpSocketServer 
    public static void main(String[] args) 
        try 
            ServerSocket server=new ServerSocket(9020);
            while (true)
                Socket client=server.accept();
                client.setKeepAlive(true);
                client.setOOBInline(true);
                System.out.println("进入了1个客户机连接:"+client.getRemoteSocketAddress().toString());
                ServerThread st = new ServerThread(client);
                st.start();
            
         catch (IOException e) 
            e.printStackTrace();
        
    

ServerThread 线程类

import java.io.*;
import java.net.Socket;

/**
 * 客户机   线程 ——自动执行run
 * @author Lenovo
 */
public class ServerThread extends Thread

    private Socket client;

    /**
     * 方法描述: 用有参构造  接收主函数那边传来的 客户机
     */
    public ServerThread(Socket client) 
        this.client=client;
    


    @Override
    public void run() 
        try 
            processSocket();//调用你想执行的 使线程启动时在run方法开始执行
         catch (IOException e) 
            e.printStackTrace();
        
    


    /**
     * 调用以上方法
     */
    public void processSocket() throws IOException 
        //加入集合 便于服务器群发
        TcpTool.addSocket(client);
    

TcpTool 消息群发工具类 


import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * 聊天工具类
 * @author tarzan
 */
public class TcpTool 

    private static List<Socket> clientList=new ArrayList<Socket>();

    /**
     * 便于 验证成功后  加入客户机
     * @param socket
     */
    public static void addSocket(Socket socket) 
        clientList.add(socket);
    

    /**
     * 群发=遍历list中的all元素, 对每个元素 写出
     * @param msg
     * @throws IOException
     */
    public static void sendAll(String msg)
        for (int i = 0; i <clientList.size(); i++) 
            Socket client = clientList.get(i);
            if(clientIsClose(client))
                delSocket(client);
                i--;
                continue;
            
            try 
                OutputStream ops =  client.getOutputStream();
                ops.write((msg+"\\r\\n").getBytes());
                ops.flush();
             catch (IOException e) 
                e.printStackTrace();
            

        
    

    /**
     * 判断是否断开连接,断开返回true,没有返回false
     * @param socket
     * @return
     */
    public static Boolean clientIsClose(Socket socket)
        try
            //发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
            socket.sendUrgentData(0xFF);
            // 发送一个数据包, 如果通信正常就不会报错.  没有报错说明没有关闭., 返回false
            return false;
        catch(Exception se)
            return true;
        
    


    /**
     * 下线时删除
     * @param socket
     */
    public static void delSocket(Socket socket)
        clientList.remove(socket);
    




Tcp客户端代码


import org.springblade.core.tool.utils.StringUtil;

import java.io.*;
import java.net.Socket;

/**
 * @author tarzan
 */
public class HttpSocketClient 
    public static void main(String[] args) throws IOException 
        Socket client=new Socket("127.0.0.1",9020);
        client.setKeepAlive(true);
        client.setOOBInline(true);
        while (true) 
            try 
                if (!clientIsClose(client)) 
                    InputStream is=client.getInputStream();
                    BufferedReader reader=new BufferedReader(new InputStreamReader(is));
                    String text=reader.readLine();
                    if(StringUtil.isNotBlank(text))
                        System.out.println("来自服务端的消息:"+text);
                    
                else
                    try 
                        //断开5秒后重新连接
                        Thread.sleep(5000);
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                    client=new Socket("127.0.0.1",9020);
                
             catch (IOException e) 
                e.printStackTrace();
            
        

    

    public static Boolean clientIsClose(Socket socket)
        try
            //发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
            socket.sendUrgentData(0xFF);
            // 发送一个数据包, 如果通信正常就不会报错.  没有报错说明没有关闭., 返回false
            return false;
        catch(Exception se)
            return true;
        
    

运行一个服务端,启动多个客户端进行测试。

控制台输出

 以上只是实现的最简单的demo,服务端,因为服务端和客户端都需要不断监听彼此通信,发送消息时候,需要另起一个线程,调用TcpTool工具类想客户端群发消息。

以上是关于java BIO tcp服务端向客户端消息群发代码教程实战的主要内容,如果未能解决你的问题,请参考以下文章

JAVA NIO 异步TCP服务端向客户端消息群发代码教程实战

java tcp服务端向客户端消息群发代码教程实战

基于java的聊天室/群发控制台程序

SpringBoot+Vue+Websocket 实现服务器端向客户端主动发送消息

C/S模型:TCP,UDP构建客户端和服务器端(BIO实现

BIO~~