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)发送心跳包给服务端。


相关文章
|
2月前
|
安全 Java API
JAVA并发编程JUC包之CAS原理
在JDK 1.5之后,Java API引入了`java.util.concurrent`包(简称JUC包),提供了多种并发工具类,如原子类`AtomicXX`、线程池`Executors`、信号量`Semaphore`、阻塞队列等。这些工具类简化了并发编程的复杂度。原子类`Atomic`尤其重要,它提供了线程安全的变量更新方法,支持整型、长整型、布尔型、数组及对象属性的原子修改。结合`volatile`关键字,可以实现多线程环境下共享变量的安全修改。
|
3月前
|
安全 Java 调度
解锁Java并发编程高阶技能:深入剖析无锁CAS机制、揭秘魔法类Unsafe、精通原子包Atomic,打造高效并发应用
【8月更文挑战第4天】在Java并发编程中,无锁编程以高性能和低延迟应对高并发挑战。核心在于无锁CAS(Compare-And-Swap)机制,它基于硬件支持,确保原子性更新;Unsafe类提供底层内存操作,实现CAS;原子包java.util.concurrent.atomic封装了CAS操作,简化并发编程。通过`AtomicInteger`示例,展现了线程安全的自增操作,突显了这些技术在构建高效并发程序中的关键作用。
69 1
|
1月前
|
Java 流计算
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
37 1
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
|
22天前
|
Java
[Java]Socket套接字(网络编程入门)
本文介绍了基于Java Socket实现的一对一和多对多聊天模式。一对一模式通过Server和Client类实现简单的消息收发;多对多模式则通过Server类维护客户端集合,并使用多线程实现实时消息广播。文章旨在帮助读者理解Socket的基本原理和应用。
18 1
|
1月前
|
Java Apache Maven
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
Java/Spring项目的包开头为什么是com?
|
1月前
|
网络协议 安全 Java
Java Socket原理
Java Socket原理是指在Java中通过Socket实现的网络通信的基础理论与机制。Socket是网络中不同设备间通信的一种标准方式,它允许应用程序之间通过TCP/IP等协议进行数据交换。在Java中,利用Socket编程可以方便地创建客户端与服务器端应用,实现跨网络的数据传输功能,是互联网软件开发中的重要技术之一。它支持多种通信模式,如可靠的流式套接字(TCP)和数据报式套接字(UDP)。
|
2月前
|
Java API 数据处理
Java 包(package)的作用详解
在 Java 中,包(package)用于组织和管理类与接口,具有多项关键作用:1)系统化组织代码,便于理解和维护;2)提供命名空间,避免类名冲突;3)支持访问控制,如 public、protected、默认和 private,增强封装性;4)提升代码可维护性,实现模块化开发;5)简化导入机制,使代码更简洁;6)促进模块化编程,提高代码重用率;7)管理第三方库,避免命名冲突;8)支持 API 设计,便于功能调用;9)配合自动化构建工具,优化项目管理;10)促进团队协作,明确模块归属。合理运用包能显著提升代码质量和开发效率。
|
2月前
|
Java 数据安全/隐私保护
Java 包(package)的使用详解
Java中的包(`package`)用于组织类和接口,避免类名冲突并控制访问权限,提升代码的可维护性和可重用性。通过`package`关键字定义包,创建相应目录结构即可实现。包可通过`import`语句导入,支持导入具体类或整个包。Java提供多种访问权限修饰符(`public`、`protected`、`default`、`private`),以及丰富的标准库包(如`java.lang`、`java.util`等)。合理的包命名和使用对大型项目的开发至关重要。
|
30天前
|
Java 数据库连接
深入探索研究Java中的异常处理机制
【10月更文挑战第8天】
14 0
|
3月前
|
Java Maven 数据库