免费图片编辑网站北京鑫旺路桥建设有限公司网站

当前位置: 首页 > news >正文

免费图片编辑网站,北京鑫旺路桥建设有限公司网站,ip做网站域名,泊头网站建设公司Java的Socket通信的断网重连的正确写法 Socket通信的断网重连介绍客户端与服务端源码演示截图本地演示服务器演示演示截图 总结 Socket通信的断网重连介绍 针对于已经建立通信的客户端与服务器#xff0c;当客户端与服务器因为网络问题导致网络不通而断开连接了或者由于服务器… Java的Socket通信的断网重连的正确写法 Socket通信的断网重连介绍客户端与服务端源码演示截图本地演示服务器演示演示截图 总结 Socket通信的断网重连介绍 针对于已经建立通信的客户端与服务器当客户端与服务器因为网络问题导致网络不通而断开连接了或者由于服务器端的服务被突然停掉而客户端进行的一种尝试重新建立连接的操作我采用的是Socket自带的往通道内写数据是否成功来判断当前连接是否断开采用该方式的好处是简洁易懂高效通用。 一般的采用ping命令定时尝试重新建立新的连接的方式都有一些不足之处前者是没办法针对端口进行判断效果不好后者则是每次都建立新的连接导致服务器端压力会较大而且相对的代码逻辑也会更加复杂。而采用本文介绍的写数据的方式即可简单判断连接是否断开原理是当连接断开后写数据时会报错捕获该错误即可底层原理则是Java的Socket底层代码采用C语言或者C编写在那里肯定是去判断IP和端口是否可以访问到的逻辑有需要的话下篇文章可以查看源码进一步熟悉Java的网络编程知识。 客户端与服务端源码 为了方便演示和理解仅进行了服务端向客户端发送数据客户端接收数据的单向通信方式实际扩展也非常简单。可以由读者进行尝试实现增加网络编程知识的熟练度。 服务端 package com;import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.Scanner;/*** author BBYH/ public class MyServerSocket {public static final Integer PORT 8080;private static Socket myServerSocket;private static OutputStream outputStream;public static void listen() {System.out.println(服务端监听端口 PORT);new Thread(() - {try (ServerSocket serverSocket new ServerSocket(PORT)) {while (true) {try {myServerSocket serverSocket.accept();System.out.println(服务端接收到来自客户端的连接);outputStream myServerSocket.getOutputStream();new Thread(() - {Scanner scanner new Scanner(System.in);while (true) {try {System.out.println(向客户端发送消息);String sendContent scanner.next();outputStream.write(sendContent.getBytes(StandardCharsets.UTF_8));} catch (Exception e) {e.printStackTrace();}}}).start();} catch (IOException e) {throw new RuntimeException(e);}}} catch (IOException e) {e.printStackTrace();}}).start();}public static void main(String[] args) {listen();} }客户端 package com;import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.Date;/** author BBYH* description 通过socket的写数据来判断当前的socket是否连通/ public class ClientSocket {public static final String IP 127.0.0.1;public static final Integer PORT 8080;private static Socket socket;private static InputStreamReader reader;private static OutputStream outputStream;public static void main(String[] args) {// 首次建立连接connect();}public static void connect() {System.out.println(向服务端端口 PORT 申请建立连接);try {socket new Socket(IP, PORT);System.out.println(客户端与服务器端连接建立成功);reader new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8);outputStream socket.getOutputStream();// 开启读取线程openReadThread();} catch (Exception e) {e.printStackTrace();}}private static void openReadThread() {new Thread(() - {// 开启断网重连线程new Thread(() - {while (true) {if (isDisContentWithServer()) {while (true) {try {socket new Socket(IP, PORT);reader new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8);outputStream socket.getOutputStream();System.out.println(new Date() :重新建立连接成功);break;} catch (IOException e) {System.out.println(new Date() :尝试重新建立连接失败);try {Thread.sleep(3000);} catch (InterruptedException ex) {throw new RuntimeException(ex);}}}}}}).start();char[] readBuf new char[1024];while (true) {try {if (reader.ready()) {int read reader.read(readBuf);System.out.println(接收到来自服务端的消息 new String(readBuf, 0, read));}} catch (Exception e) {e.printStackTrace();}}}).start();}public static boolean isDisContentWithServer() {try {outputStream.write((发送数据).getBytes(StandardCharsets.UTF_8));Thread.sleep(3000);return false;} catch (Exception e) {return true;}} }尽管在客户端开启断网重连线程中进行了两次while循环不是很优雅但仍然可以较为清晰的理解到代码的执行逻辑即每隔固定时间3秒进行是否连通的判断当发现不连通的则进行尝试重连重新建立连接该处的逻辑没有办法省略由于客户端一般不长时间运行消耗的资源虽然较多但在程序运行结束后也自然就释放了。 演示截图 演示流程为开启服务器 – 客户端建立连接 – 服务器发送一些数据 – 服务器断开连接 – 客户端尝试重连自动进行 – 重新开启服务器 – 服务器再次发送数据 在该过程中服务器在首次开启后的关闭即代表了客户端的断网实际情况中可以采用服务器然后采用断开Wifi的方式代替这个关闭服务器只要保证了客户端与服务器无法连通即代表断网了后面的重连则可以采用再次打开Wifi重新连接上网络连接则自动建立好 本地演示 开启服务器 – 客户端建立连接 – 服务器发送一些数据 服务器断开连接 – 客户端尝试重连自动进行 重新开启服务器 – 服务器再次发送数据 服务器演示 采用的是我申请的阿里云服务器流程与上述文字说明一致采用断开Wifi的形式来代替服务器关闭的效果服务器关闭同样被我测试过与本地一样可以进行重连。由于我采用Xshell进行连接当断开连接后日志会失效所以采用后台任务记录运行打印的日志命令为 nohup java com.MyServerSocket MyServerSocket.out 关于不采用防火墙来演示断网效果则是因为防火墙无法拦截已经建立好的Socket通道经测试发现该现象读者可手动进行验证如有意外情况可向我进行反馈。 由于nohup命令的输入重定向我暂时还没研究明白所以目前服务端也不进行发送数据两边都只是简单的建立连接和断开代码进行了简单的调整如下 服务器端 package com;import java.io.IOException; import java.net.ServerSocket; import java.net.Socket;/** author BBYH/ public class MyServerSocket {public static final Integer PORT 8080;private static Socket myServerSocket;public static void listen() {System.out.println(服务端监听端口 PORT);new Thread(() - {try (ServerSocket serverSocket new ServerSocket(PORT)) {while (true) {try {myServerSocket serverSocket.accept();System.out.println(服务端接收到来自客户端的连接);} catch (IOException e) {throw new RuntimeException(e);}}} catch (IOException e) {e.printStackTrace();}}).start();}public static void main(String[] args) {listen();} }客户端 package com;import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.Date;/** author BBYH* description 通过socket的写数据来判断当前的socket是否连通*/ public class ClientSocket {public static final String IP 127.0.0.1;public static final Integer PORT 8080;private static Socket socket;private static OutputStream outputStream;public static void main(String[] args) {// 首次建立连接connect();}public static void connect() {System.out.println(向服务端端口 PORT 申请建立连接);try {socket new Socket(IP, PORT);System.out.println(客户端与服务器端连接建立成功);outputStream socket.getOutputStream();// 开启断网重连线程openReConnectThread();} catch (Exception e) {e.printStackTrace();}}private static void openReConnectThread() {new Thread(() - {while (true) {try {if (isDisContentWithServer()) {while (true) {try {socket new Socket(IP, PORT);outputStream socket.getOutputStream();System.out.println(new Date() :重新建立连接成功);break;} catch (IOException e) {System.out.println(new Date() :尝试重新建立连接失败);try {Thread.sleep(2000);} catch (InterruptedException ex) {throw new RuntimeException(ex);}}}}} catch (Exception e) {e.printStackTrace();}}}).start();}public static boolean isDisContentWithServer() {try {outputStream.write((发送数据).getBytes(StandardCharsets.UTF_8));Thread.sleep(2000);return false;} catch (Exception e) {return true;}} }演示截图 开启服务器 – 客户端建立连接 断开Wifi – 客户端尝试重新建立连接 – 重新打开Wifi – 连接成功 总结 本次断网重连演示完美结束如有疑问可在评论区进行提问