java之socket的OOBInline和UrgentData和发送心跳包研究

简介: java之socket的OOBInline和UrgentData和发送心跳包研究

UrgentData可以理解为紧急发送数据方式,如果我们客户端先用write方法写入数据,再用UrgentData发送数据,再去执行flush操作,我们可以得到服务端先打印UrgentData发送的数据,然后再打印write写入的数据。

客户端代码实现:

package com.chenyu.string.cn;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class ClientTest {
  public static Socket socket;
  public static final String LocalHOST = "127.0.0.1";
  public static final int PORT = 1234;
  public static void main(String[] args) {
    Client(LocalHOST, PORT);
  }
  public static void Client(String address, int port) {
    try {
      socket = new Socket(address, port);
    } catch (Exception e) {
      System.out.println("connection reset");
      return;
    }
    if (socket != null && socket.isConnected()) {
      try {
        socket.setOOBInline(true);
        OutputStream out = socket.getOutputStream();
          OutputStreamWriter outWriter = new OutputStreamWriter(out);
        outWriter.write(67); // 向服务器发送字符"C"
        outWriter.write("hello world\r\n");
        socket.sendUrgentData(65); // 向服务器发送字符"A"
        socket.sendUrgentData(322); // 向服务器发送字符"B"
        outWriter.flush();
        socket.sendUrgentData(214); // 向服务器发送汉字”中”
        socket.sendUrgentData(208);
        socket.sendUrgentData(185); // 向服务器发送汉字”国”
        socket.sendUrgentData(250);
        socket.close();
      } catch (Exception e) {
        System.out.println("has throw exception");
        e.printStackTrace();
      } finally {
        try {
          if (socket != null) {
            socket.close();
          }
        } catch (IOException e) {
          System.out.println("socket close fail");
        }
      }
    } else {
      System.out.println("socket is null or socket connect fail");
    }
  }
}

服务端代码实现:

package com.chenyu.string.cn;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class TestInline {
  public static ServerSocket serverSocket;
  public static Socket socket;
  public static void main(String[] args) {
    try {
      serverSocket = new ServerSocket(1234);
    } catch (IOException e1) {
      System.out.println("serverSocket is fail");
      return;
    }
    System.out.println("服务器已经启动,端口号:1234");
    while (true) {
      try {
        socket = serverSocket.accept();
        socket.setOOBInline(true);
        InputStream in = socket.getInputStream();
        InputStreamReader inReader = new InputStreamReader(in);
        BufferedReader bReader = new BufferedReader(inReader);
        String result;
        while ((result = bReader.readLine()) != null) {
          System.out.println(result);
        }
//        char [] cha = new char[1024];
//        int len = inReader.read(cha);
//        System.out.println(new String(cha,0,len));
        socket.close();
      } catch (Exception e){
        System.out.println("read data fail");
      } finally {
        if (socket != null) {
          try {
            socket.close();
          } catch (IOException e) {
            System.out.println("socket close fail");
          }
        }
      }
    }
  }
}
  socket = serverSocket.accept();
        socket.setOOBInline(true);
        InputStream in = socket.getInputStream();
        InputStreamReader inReader = new InputStreamReader(in);
        BufferedReader bReader = new BufferedReader(inReader);
        String result;
        while ((result = bReader.readLine()) != null) {
          System.out.println(result);
        }
//        char [] cha = new char[1024];
//        int len = inReader.read(cha);
//        System.out.println(new String(cha,0,len));
        socket.close();
      } catch (Exception e){
        System.out.println("read data fail");
      } finally {
        if (socket != null) {
          try {
            socket.close();
          } catch (IOException e) {
            System.out.println("socket close fail");
          }
        }
      }
    }
  }
}

socket = serverSocket.accept();

   socket.setOOBInline(true);

   InputStream in = socket.getInputStream();

   InputStreamReader inReader = new InputStreamReader(in);

   BufferedReader bReader = new BufferedReader(inReader);

   String result;

   while ((result = bReader.readLine()) != null) {

    System.out.println(result);

   }

//    char [] cha = new char[1024];

//    int len = inReader.read(cha);

//    System.out.println(new String(cha,0,len));

   socket.close();

  } catch (Exception e){

   System.out.println("read data fail");

  } finally {

   if (socket != null) {

    try {

     socket.close();

    } catch (IOException e) {

     System.out.println("socket close fail");

    }

   }

  }

 }

}

}

运行结果(先运行服务端,后运行客户端):

服务器已经启动,端口号:1234
ABChello world
中国

说明使用sendUrgentData方法发送数据后,系统会立即将这些数据发送出去;而使用write发送数据,必须要使用flush方法才会真正发送数据。

在使用setOOBInline方法打开SO_OOBINLINE选项时要注意是必须在客户端和服务端程序同时使用setOOBInline方法打开这个选项,否则无法命名用sendUrgentData来发送数据。

总结:

我们还可以通过socket.sendUrgentData(0xff);来检测是否与服务端连通,和ping IP 效果差不多,其它的socket.isConnected() socket.isOutputShutdown()都是本地检测,我们上面socket发送数据,如果在安卓客户端,我们可以用这个来发送心跳包,

类似上面客户端的代码,通过后台下发的IP和端口配置,开启线程,out.write(data),通过handler.postDelay(Runable, delayTime)发送心跳包给服务端。


相关文章
|
消息中间件 算法 安全
JUC并发—1.Java集合包底层源码剖析
本文主要对JDK中的集合包源码进行了剖析。
|
安全 Java API
JAVA并发编程JUC包之CAS原理
在JDK 1.5之后,Java API引入了`java.util.concurrent`包(简称JUC包),提供了多种并发工具类,如原子类`AtomicXX`、线程池`Executors`、信号量`Semaphore`、阻塞队列等。这些工具类简化了并发编程的复杂度。原子类`Atomic`尤其重要,它提供了线程安全的变量更新方法,支持整型、长整型、布尔型、数组及对象属性的原子修改。结合`volatile`关键字,可以实现多线程环境下共享变量的安全修改。
|
安全 Java 调度
解锁Java并发编程高阶技能:深入剖析无锁CAS机制、揭秘魔法类Unsafe、精通原子包Atomic,打造高效并发应用
【8月更文挑战第4天】在Java并发编程中,无锁编程以高性能和低延迟应对高并发挑战。核心在于无锁CAS(Compare-And-Swap)机制,它基于硬件支持,确保原子性更新;Unsafe类提供底层内存操作,实现CAS;原子包java.util.concurrent.atomic封装了CAS操作,简化并发编程。通过`AtomicInteger`示例,展现了线程安全的自增操作,突显了这些技术在构建高效并发程序中的关键作用。
294 1
|
11月前
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
523 0
|
前端开发 JavaScript Java
[Java计算机毕设]基于ssm的OA办公管理系统的设计与实现,附源码+数据库+论文+开题,包安装调试
OA办公管理系统是一款基于Java和SSM框架开发的B/S架构应用,适用于Windows系统。项目包含管理员、项目管理人员和普通用户三种角色,分别负责系统管理、请假审批、图书借阅等日常办公事务。系统使用Vue、HTML、JavaScript、CSS和LayUI构建前端,后端采用SSM框架,数据库为MySQL,共24张表。提供完整演示视频和详细文档截图,支持远程安装调试,确保顺利运行。
543 17
|
Java 物联网 定位技术
Java socket获取gps定位
通过Java Socket编程获取GPS定位信息可以实现实时的地理位置跟踪。本文介绍了如何搭建Socket服务器、解析GPS数据以及实现客户端发送GPS数据的流程。希望这篇文章能为开发者提供清晰的指导,帮助构建高效的GPS定位系统。
491 7
|
Java 流计算
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
271 2
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
|
Java Android开发
Eclipse 创建 Java 包
Eclipse 创建 Java 包
305 1
|
网络协议 安全 Java
Java Socket原理
Java Socket原理是指在Java中通过Socket实现的网络通信的基础理论与机制。Socket是网络中不同设备间通信的一种标准方式,它允许应用程序之间通过TCP/IP等协议进行数据交换。在Java中,利用Socket编程可以方便地创建客户端与服务器端应用,实现跨网络的数据传输功能,是互联网软件开发中的重要技术之一。它支持多种通信模式,如可靠的流式套接字(TCP)和数据报式套接字(UDP)。
406 10
|
Java Apache Maven
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
1248 0
Java/Spring项目的包开头为什么是com?