Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java TCP心跳信号无法正常工作_Java_Android_Sockets_Tcp_Ioexception - Fatal编程技术网

Java TCP心跳信号无法正常工作

Java TCP心跳信号无法正常工作,java,android,sockets,tcp,ioexception,Java,Android,Sockets,Tcp,Ioexception,项目:我一直在为android开发一款无线鼠标应用程序,它利用TCP作为传输鼠标移动的网络协议 目标: 我认为实现心跳时间任务是查看服务器是否已关闭的最佳方法。每5秒钟,如果没有移动鼠标(鼠标移动会将计时器重置回5),就会向服务器发送阵列中2字节的心跳信号。因此,如果服务器关闭,则在发送心跳信号后会引发IOException(断管) 我的问题: 除了在抛出异常之前循环3次之外,heartbeat工作正常。目前,我已将其设置为5秒,然后再发送心跳。它将在服务器关闭后发送三次心跳(15秒而不是5秒)

项目:我一直在为android开发一款无线鼠标应用程序,它利用TCP作为传输鼠标移动的网络协议

目标: 我认为实现心跳时间任务是查看服务器是否已关闭的最佳方法。每5秒钟,如果没有移动鼠标(鼠标移动会将计时器重置回5),就会向服务器发送阵列中2字节的心跳信号。因此,如果服务器关闭,则在发送心跳信号后会引发
IOException(断管)

我的问题: 除了在抛出异常之前循环3次之外,heartbeat工作正常。目前,我已将其设置为5秒,然后再发送心跳。它将在服务器关闭后发送三次心跳(15秒而不是5秒),然后引发预期的异常

我可能会将心跳间隔设置为2秒,这反过来需要6秒来引发异常,但我想知道为什么第一次它不起作用

心跳代码:

 Timer task = new Timer();
                task.scheduleAtFixedRate(new TimerTask() {
                    @Override
                    public void run() {
                        if (heartbeat == 1) {
                            byte buf[] = {-96, -96};
                            try {
                                bos.write(buf); // Buffered output stream
                                bos.flush(); // Exception gets thrown here
                                heartbeat = 5;
                                System.out.println("Testing 3");
                            } catch (IOException e) {
                                System.out.println("Testing 2");
                                launchHomescreen();
                                this.cancel();
                                e.printStackTrace();
                            }
                        } else {
                            System.out.println("Testing 1" + heartbeat);
                            heartbeat--;
                        }
                    }
                }, 1000, 1000);
04-27 00:33:02.339  25410-26259/com.tutorials.jurko.androidmouse I/System.out﹕ Message sending: -99 -99 <-- This is the mouse click that should stop the server
04-27 00:33:03.190  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 15
04-27 00:33:04.201  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 14
04-27 00:33:05.192  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 13
04-27 00:33:06.193  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 12
04-27 00:33:07.203  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 3 <- Should throw the exception here
04-27 00:33:08.194  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 15
04-27 00:33:09.195  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 14
04-27 00:33:10.196  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 13
04-27 00:33:11.187  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 12
04-27 00:33:12.188  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 3
04-27 00:33:13.189  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 15
04-27 00:33:14.190  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 14
04-27 00:33:15.191  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 13
04-27 00:33:16.202  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 12
04-27 00:33:17.193  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 2 <- but doesn't do it till the third heartbeat
04-27 00:33:17.233  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ java.net.SocketException: sendto failed: EPIPE (Broken pipe)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:499)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.IoBridge.sendto(IoBridge.java:468)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.net.PlainSocketImpl.write(PlainSocketImpl.java:508)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:270)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at com.tutorials.jurko.androidmouse.MainActivity$connectTask$1.run(MainActivity.java:496)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.util.Timer$TimerImpl.run(Timer.java:284)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.Posix.sendtoBytes(Native Method)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.Posix.sendto(Posix.java:156)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.IoBridge.sendto(IoBridge.java:466)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ ... 7 more
04-27 00:33:17.453  25410-25410/com.tutorials.jurko.androidmouse W/ApplicationPackageManager﹕ getCSCPackageItemText()
04-27 00:33:33.139  25410-25410/com.tutorials.jurko.androidmouse W/IInputConnectionWrapper﹕ getCursorCapsMode on inactive InputConnection
        Timer task = new Timer();
        task.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                if (heartbeat == 0) {
                    byte buf[] = {-96, -96};
                    byte send[] = new byte[1024]; // Added this
                    try {
                        socket.setSoTimeout(1000); // Added a timeout every read call
                        bos.write(buf); // Buffered output stream
                        bos.flush();
                        if(socket.getInputStream().read(send) == -1) { // End of stream reached
                            System.out.println("Testing 2");
                            launchHomescreen();
                            this.cancel();
                        }
                        heartbeat = 2;
                        System.out.println("Testing 3");
                    } catch (IOException e) {
                        System.out.println("Testing 2");
                        launchHomescreen();
                        this.cancel();
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("Testing 1" + heartbeat);
                    heartbeat--;
                }
            }
        }, 1000, 1000);
调试语句日志:

 Timer task = new Timer();
                task.scheduleAtFixedRate(new TimerTask() {
                    @Override
                    public void run() {
                        if (heartbeat == 1) {
                            byte buf[] = {-96, -96};
                            try {
                                bos.write(buf); // Buffered output stream
                                bos.flush(); // Exception gets thrown here
                                heartbeat = 5;
                                System.out.println("Testing 3");
                            } catch (IOException e) {
                                System.out.println("Testing 2");
                                launchHomescreen();
                                this.cancel();
                                e.printStackTrace();
                            }
                        } else {
                            System.out.println("Testing 1" + heartbeat);
                            heartbeat--;
                        }
                    }
                }, 1000, 1000);
04-27 00:33:02.339  25410-26259/com.tutorials.jurko.androidmouse I/System.out﹕ Message sending: -99 -99 <-- This is the mouse click that should stop the server
04-27 00:33:03.190  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 15
04-27 00:33:04.201  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 14
04-27 00:33:05.192  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 13
04-27 00:33:06.193  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 12
04-27 00:33:07.203  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 3 <- Should throw the exception here
04-27 00:33:08.194  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 15
04-27 00:33:09.195  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 14
04-27 00:33:10.196  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 13
04-27 00:33:11.187  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 12
04-27 00:33:12.188  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 3
04-27 00:33:13.189  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 15
04-27 00:33:14.190  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 14
04-27 00:33:15.191  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 13
04-27 00:33:16.202  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 12
04-27 00:33:17.193  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 2 <- but doesn't do it till the third heartbeat
04-27 00:33:17.233  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ java.net.SocketException: sendto failed: EPIPE (Broken pipe)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:499)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.IoBridge.sendto(IoBridge.java:468)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.net.PlainSocketImpl.write(PlainSocketImpl.java:508)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:270)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at com.tutorials.jurko.androidmouse.MainActivity$connectTask$1.run(MainActivity.java:496)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.util.Timer$TimerImpl.run(Timer.java:284)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.Posix.sendtoBytes(Native Method)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.Posix.sendto(Posix.java:156)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.IoBridge.sendto(IoBridge.java:466)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ ... 7 more
04-27 00:33:17.453  25410-25410/com.tutorials.jurko.androidmouse W/ApplicationPackageManager﹕ getCSCPackageItemText()
04-27 00:33:33.139  25410-25410/com.tutorials.jurko.androidmouse W/IInputConnectionWrapper﹕ getCursorCapsMode on inactive InputConnection
        Timer task = new Timer();
        task.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                if (heartbeat == 0) {
                    byte buf[] = {-96, -96};
                    byte send[] = new byte[1024]; // Added this
                    try {
                        socket.setSoTimeout(1000); // Added a timeout every read call
                        bos.write(buf); // Buffered output stream
                        bos.flush();
                        if(socket.getInputStream().read(send) == -1) { // End of stream reached
                            System.out.println("Testing 2");
                            launchHomescreen();
                            this.cancel();
                        }
                        heartbeat = 2;
                        System.out.println("Testing 3");
                    } catch (IOException e) {
                        System.out.println("Testing 2");
                        launchHomescreen();
                        this.cancel();
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("Testing 1" + heartbeat);
                    heartbeat--;
                }
            }
        }, 1000, 1000);

04-27 00:33:02.339 25410-26259/com.tutorials.jurko.androidmouse I/System.out﹕ 消息发送:-99-99由于TCP缓冲和异步,“连接重置”/“断管”不会立即发生。它发生在写入事件在未收到ACK时超时之后,这可能需要相当一小部分时间


它不一定与写入尝试次数有关,因此更改间隔不一定会有帮助。

如果要确定连接状态,请尝试在套接字上执行
recv
,而不是发送心跳消息<如果服务器关闭且连接消失,则code>recv
将返回零。尽管对于由于n/w问题而无法访问服务器的情况,这仍然会失败

若客户端和服务器都发送数据包并相互确认,那个么应用程序保持活动状态将工作得最好。取决于破裂的管道将不能完全满足要求


另一个选项是在TCP上启用
保持活动状态。

谢谢你们的响应,我解决问题的方法是在写入之前向套接字添加超时,然后再添加读取。如果读取返回-1,则我知道服务器已停止。这个解决方案似乎也正是我想要的

新代码:

 Timer task = new Timer();
                task.scheduleAtFixedRate(new TimerTask() {
                    @Override
                    public void run() {
                        if (heartbeat == 1) {
                            byte buf[] = {-96, -96};
                            try {
                                bos.write(buf); // Buffered output stream
                                bos.flush(); // Exception gets thrown here
                                heartbeat = 5;
                                System.out.println("Testing 3");
                            } catch (IOException e) {
                                System.out.println("Testing 2");
                                launchHomescreen();
                                this.cancel();
                                e.printStackTrace();
                            }
                        } else {
                            System.out.println("Testing 1" + heartbeat);
                            heartbeat--;
                        }
                    }
                }, 1000, 1000);
04-27 00:33:02.339  25410-26259/com.tutorials.jurko.androidmouse I/System.out﹕ Message sending: -99 -99 <-- This is the mouse click that should stop the server
04-27 00:33:03.190  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 15
04-27 00:33:04.201  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 14
04-27 00:33:05.192  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 13
04-27 00:33:06.193  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 12
04-27 00:33:07.203  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 3 <- Should throw the exception here
04-27 00:33:08.194  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 15
04-27 00:33:09.195  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 14
04-27 00:33:10.196  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 13
04-27 00:33:11.187  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 12
04-27 00:33:12.188  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 3
04-27 00:33:13.189  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 15
04-27 00:33:14.190  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 14
04-27 00:33:15.191  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 13
04-27 00:33:16.202  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 12
04-27 00:33:17.193  25410-26264/com.tutorials.jurko.androidmouse I/System.out﹕ Testing 2 <- but doesn't do it till the third heartbeat
04-27 00:33:17.233  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ java.net.SocketException: sendto failed: EPIPE (Broken pipe)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:499)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.IoBridge.sendto(IoBridge.java:468)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.net.PlainSocketImpl.write(PlainSocketImpl.java:508)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:270)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at com.tutorials.jurko.androidmouse.MainActivity$connectTask$1.run(MainActivity.java:496)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at java.util.Timer$TimerImpl.run(Timer.java:284)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe)
04-27 00:33:17.243  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.Posix.sendtoBytes(Native Method)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.Posix.sendto(Posix.java:156)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ at libcore.io.IoBridge.sendto(IoBridge.java:466)
04-27 00:33:17.253  25410-26264/com.tutorials.jurko.androidmouse W/System.err﹕ ... 7 more
04-27 00:33:17.453  25410-25410/com.tutorials.jurko.androidmouse W/ApplicationPackageManager﹕ getCSCPackageItemText()
04-27 00:33:33.139  25410-25410/com.tutorials.jurko.androidmouse W/IInputConnectionWrapper﹕ getCursorCapsMode on inactive InputConnection
        Timer task = new Timer();
        task.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                if (heartbeat == 0) {
                    byte buf[] = {-96, -96};
                    byte send[] = new byte[1024]; // Added this
                    try {
                        socket.setSoTimeout(1000); // Added a timeout every read call
                        bos.write(buf); // Buffered output stream
                        bos.flush();
                        if(socket.getInputStream().read(send) == -1) { // End of stream reached
                            System.out.println("Testing 2");
                            launchHomescreen();
                            this.cancel();
                        }
                        heartbeat = 2;
                        System.out.println("Testing 3");
                    } catch (IOException e) {
                        System.out.println("Testing 2");
                        launchHomescreen();
                        this.cancel();
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("Testing 1" + heartbeat);
                    heartbeat--;
                }
            }
        }, 1000, 1000);

您是否看过客户端和服务器之间通信的
tcpdump
?看起来服务器没有显式地关闭套接字,并且堆栈中的其他位置出现了10秒的超时。