【问题标题】:JAVA SOCKET realize disconnect after two writesJAVA SOCKET实现两次写入后断开连接
【发布时间】:2020-05-08 22:05:10
【问题描述】:

PC 中使用 JAVA io.socket 的应用程序,它将 json 发送到 LAN 网络上 TCP 上的服务器设备 ESP8266

当您连接并且从 java 执行断开序列时,一切正常。

java 是客户端,设备是服务器,当设备断开连接时(这里让我们在 localhost 上使用 Hercules),java 程序不会被注意到,当我尝试使用 outputstreamwriter 编写时它不会触发异常,异常将被执行在服务器断开连接后至少两次写入套接字并且服务器未接收到的最后两次写入将返回成功!在爪哇。我读过其他程序员使用字节发送来查看连接是否仍然存在。同样的问题也存在。如果我每 20 秒发送两次写入,则在 Java 实现服务器断开连接之前的 60 秒之间,如果我每 1 秒发送一次,将会有很多 ATcommand 中断。

这是我的代码:

    public boolean Write(String data){
    System.out.println("StartSending");
    if(TESocket.Connected)
    {

        Thread write = new Thread(new Runnable() {
            @Override
            public void run() {
                try
                {
                    outputStreamWriter.write(data);
                    outputStreamWriter.flush();
                }
                catch (IOException e)
                {
                    TESocket.Connected=false;
                    System.out.println("Faild");
                    System.out.println(e.getCause());
                }
            }
        });
        write.start();

        return true;
    }
    else
    {
        System.out.println("Not Connected");
        return false;
    }
}

TESocket 是使用 Runnable 处理 Socket 的类,而 Connected 是一个静态布尔值,因为一次只有一个套接字,这里是连接方法

 public boolean  Connect(){
    Thread connect = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                socket= new Socket("127.0.0.1",Integer.parseInt(port));
                if(socket.isConnected())
                {
                    inputStreamReader  = new InputStreamReader(socket.getInputStream());
                    outputStreamWriter = new OutputStreamWriter(socket.getOutputStream());
                    TESocket.Connected=true;
                    System.out.println("Connected");
                }

            } catch (IOException e) {
                System.out.println("Faild to Connect");
                e.printStackTrace();
            }
        }
    });
    connect.start();
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    if(TESocket.Connected)
        return true;
    else
        return false;
}

如果服务器在发送写入后立即无法访问,我怎么能注意到?或者有没有注意到这一点的事件?也许是一些异步套接字之王?就像在 QT(断开信号槽)中一样

【问题讨论】:

  • 你不能。这就是 TCP 的工作原理。
  • 很好地解决问题,几分钟后发帖

标签: java sockets server connection


【解决方案1】:

通过阅读方法和设置超时解决了这个问题,感谢阅读一些帖子 在读取中,如果我仍然连接并且没有接收到任何数据超时将被抛出,这使我回到 while 循环的第一个谎言

如果我收到数据,我将大于零,哪个阅读器将读取数据并标记 rec=true,因此断开序列不会发生

如果我没有收到任何数据并且没有发生超时,rec=false 并且不会抛出异常,因此程序将断开例程 将超时设置为 1 毫秒使其在截止日期检测中实时(与我的工作成正比)

public boolean Read()
{
    if (TESocket.Connected)
    {
        try {
            socket.setSoTimeout(1000);
        } catch (SocketException e) {
            System.out.println("Problem Timeout");
            e.printStackTrace();
        }
        Thread read = new Thread(new Runnable() {
            @Override
            public void run() {
                int i;
                boolean rec=false;
                while (true)
                {
                    char[] reader = new char[250];
                    try {

                            //while(!inputStreamReader.ready());
                            i=inputStreamReader.read(reader);
                            if(i>0) {
                                System.out.println(reader);
                                rec=true;
                            }
                            // Thread.sleep(2500);
                        if(!rec)
                        {
                            System.out.println("Disconnected");
                            TESocket.Connected=false;
                            inputStreamReader.close();
                            outputStreamWriter.close();
                            socket.close();
                            break;
                        }
                        rec=false;

                    }
                    catch (IOException e)
                    {
                        System.out.println("Connected");
                    }
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        });
        read.start();
    }
    return true;
}

【讨论】:

  • 读取超时并不能解决立即写入失败的问题。
  • 也不表示连接失效。
  • 它会看到断开连接并将布尔值设置为 false 。从那里我每次想写时检查该连接是否存在,这对我来说非常有效,我实际上通过了那部分代码,可能应该在给出分数之前对其进行测试!比你说的没什么好!
  • 读取超时不会“看到断开连接”。没有断开连接。它看到的是在超时期限内没有数据到达,并且 包含 断开连接。如果在超时期限内断开连接,则不会超时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多