相关疑难解决方法(0)

为什么在没有尝试I/O的情况下检测TCP套接字是否被对等端正常关闭是不可能的?

作为最近一个问题的后续内容,我想知道为什么在没有尝试在TCP套接字上进行读/写操作的情况下,为什么Java不可能检测到套接字已被对等端正常关闭?无论是使用前NIO Socket还是NIO ,情况似乎都是如此SocketChannel.

当对等体正常关闭TCP连接时,连接两端的TCP堆栈都知道这一事实.服务器端(启动关闭的那个)最终处于状态FIN_WAIT2,而客户端(未明确响应关闭的那个)最终处于状态CLOSE_WAIT.为什么没有一个方法SocketSocketChannel可以查询TCP堆栈看到底层的TCP连接是否已经终止?是不是TCP堆栈没有提供这样的状态信息?或者这是一个设计决定,以避免昂贵的内核调用?

在已经发布了这个问题的答案的用户的帮助下,我想我会看到问题可能来自哪里.未明确关闭连接的一方最终处于TCP状态,CLOSE_WAIT这意味着连接正在关闭并等待一方发出自己的CLOSE操作.我认为isConnected返回trueisClosed返回是公平的false,但为什么不存在类似的东西isClosing呢?

以下是使用pre-NIO套接字的测试类.但使用NIO可获得相同的结果.

import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
  public static void main(String[] args) throws Exception {
    final ServerSocket ss = new ServerSocket(12345);
    final Socket cs = ss.accept();
    System.out.println("Accepted connection");
    Thread.sleep(5000);
    cs.close();
    System.out.println("Closed connection");
    ss.close();
    Thread.sleep(100000);
  }
}


import java.net.Socket;

public class MyClient {
  public static …
Run Code Online (Sandbox Code Playgroud)

java sockets network-programming tcp

89
推荐指数
5
解决办法
3万
查看次数

Java套接字API:如何判断连接是否已关闭?

我遇到了Java套接字API的一些问题.我正在尝试显示当前连接到我的游戏的玩家数量.很容易确定玩家何时连接.但是,确定玩家何时使用套接字API断开连接似乎不必要.

调用isConnected()已远程断开的套接字似乎总是返回true.同样,调用isClosed()已远程关闭的套接字似乎总是返回false.我已经读过,要实际确定套接字是否已关闭,必须将数据写入输出流并且必须捕获异常.这似乎是处理这种情况的一种非常不洁净的方式.我们不得不经常通过网络垃圾邮件垃圾邮件,以便知道套接字何时关闭.

还有其他解决方案吗?

java sockets networking client-server

82
推荐指数
2
解决办法
9万
查看次数

如何检查Socket目前是否在Java中连接?

我试图找出Java TCP套接字当前是否连接,以下似乎只是告诉我套接字是否已经连接 - 而不是它当前是否仍然连接.

socket.isConnected();
Run Code Online (Sandbox Code Playgroud)

任何帮助表示感谢,谢谢.

java sockets tcp

25
推荐指数
2
解决办法
11万
查看次数

在Java/Android中更快地检测到损坏的套接字

背景

我的应用程序从手机收集数据并将其发送到远程服务器.
数据首先存储在内存中(或者当文件足够大时存储在文件中),每隔X秒左右,应用程序就会刷新该数据并将其发送到服务器.

关键是每一条数据都成功发送,我宁愿发送两次数据而不是发送数据.

问题

作为测试,我将应用程序设置为每5秒发送一个带有时间戳的数据,这意味着服务器上每5秒出现一个新行.
如果我杀了服务器,我希望线路停止,现在应该将它们写入内存.

当我再次启用服务器时,我应该能够确认没有任何事件丢失.

然而问题是,当我杀死服务器时,IO操作开始失败大约需要20秒,这意味着在这20秒内,应用程序会愉快地发送事件并将其从内存中删除,但它们永远不会到达服务器并永远丢失.

我需要一种方法来确保数据实际到达服务器.

这可能是最基本的TCP问题之一,但并非如此,我还没有找到任何解决方案.

我试过的东西

附加信息

我无法改变服务器如何响应意味着我无法告诉服务器确认数据(不仅仅是TCP的机制),服务器只是默默地接受数据而不发回任何东西.

代码片段

课程初始化:

socket = new Socket(host, port);
socket.setTcpNoDelay(true);
Run Code Online (Sandbox Code Playgroud)

数据发送的位置:

while(!dataList.isEmpty()) {
    String data = dataList.removeFirst();
    inMemoryCount -= data.length();
    try {
        OutputStream os = socket.getOutputStream();
        os.write(data.getBytes());
        os.flush();
    }
    catch(IOException e) {
        inMemoryCount += data.length();
        dataList.addFirst(data);
        socket = null;
        return false;
    }
}

return true;
Run Code Online (Sandbox Code Playgroud)

更新1

我再说一遍,我无法改变服务器的行为方式.
它通过TCP和UPD接收数据,并且不会发送任何数据以确认接收.这是一个事实,并且在一个完美的世界中,服务器会确认数据,但这根本不会发生.


更新2

Fraggle发布的解决方案非常完美(关闭套接字并等待输入流关闭).

然而,这带来了一系列新问题.
由于我在手机上,我必须假设用户无法发送无限量的字节,并且我希望尽可能将所有数据流量保持在最低限度.

我不担心打开一个新套接字的开销,这几个字节不会有所作为.然而,我担心的是,每次我连接到服务器时,我都必须发送一个短字符串来标识我是谁.

字符串本身不是那么长(大约30个字符)但如果我经常关闭并打开套接字会增加.

一种解决方案只是每隔X字节"刷新"一次数据,问题是我必须明智地选择X; 如果太大,如果套接字发生故障,将发送过多的重复数据,如果它太小,则开销太大.


最后更新

我的最终解决方案是通过每X字节关闭它来"刷新"套接字,如果一切都不顺利,那么X字节将再次发送.

这可能会在服务器上创建一些重复事件,但可以在那里进行过滤.

java networking android tcp

10
推荐指数
1
解决办法
7217
查看次数

如何检测TCP套接字断开(使用C Berkeley套接字)

我正在使用循环从交流Berkeley套接字读取消息,但我无法检测套接字何时断开连接,所以我接受新的连接.请帮忙

while(true) {
            bzero(buffer,256);
            n = read(newsockfd,buffer,255);
            printf("%s\n",buffer);        
}
Run Code Online (Sandbox Code Playgroud)

c sockets network-programming tcp

9
推荐指数
1
解决办法
2万
查看次数

isConnected和isClosed之间的区别

我会假设调用isConnected()套接字会告诉我是否连接到另一端.

返回:如果套接字成功连接到服务器,则返回true

但经过检查然后调用flush()我得到的套接字

java.net.SocketException:管道损坏

怎么isConnected比不同isClosed,什么是每一个真正的行为?

如何在不向流写入任何内容或创建新连接的情况下正式关闭另一方?还有办法吗?

java sockets

2
推荐指数
1
解决办法
1915
查看次数

是否可以知道RS232端口的连接状态?

你们建议使用9针电缆中的哪个信号/针来检查连接状态?

到目前为止,我正在使用DSR信号,因为在硬件测试中,如果电缆正确连接,则如果断开连接,则DSR信号为1,DSR变为0。但是,与其他驱动程序和/或操作系统相比,DSR在消息传输过程中会发生变化或始终为0。因此,除非在晴天在25ºC的受控条件下,否则我认为此DSR信号并不可靠。

那么如何在给定的时间点知道我是否仍在连接,即电缆没有断开?

请注意,连接可能会丢失,并且我的串行端口仍然存在并且已在操作系统的端口列表中打开,因此检查端口是否存在无法解决任何问题。我唯一的希望是依靠9个引脚之一进行检查。

另外,我也不想发送或接收字节来检查连接状态。应该有更好的方法...

谢谢!

serial-port

2
推荐指数
1
解决办法
3072
查看次数