相关疑难解决方法(0)

如何检测远程侧插座关闭?

如何检测是否Socket#close()已在远程端的套接字上调用?

java sockets networking tcp

82
推荐指数
3
解决办法
14万
查看次数

Java套接字和丢弃的连接

检测套接字是否被丢弃的最合适方法是什么?或者是否确实发送了数据包?

我有一个库,可以通过Apple gatways(可在GitHub上获得)向Apple发送Apple推送通知.客户端需要打开套接字并发送每条消息的二进制表示; 但不幸的是,Apple没有回复任何确认.连接可以重复使用以发送多条消息.我正在使用简单的Java Socket连接.相关代码是:

Socket socket = socket();   // returns an reused open socket, or a new one
socket.getOutputStream().write(m.marshall());
socket.getOutputStream().flush();
logger.debug("Message \"{}\" sent", m);
Run Code Online (Sandbox Code Playgroud)

在某些情况下,如果在发送消息时或之前删除了连接; Socket.getOutputStream().write()虽然成功完成了.我预计这是由于TCP窗口尚未用完.

有没有办法可以确定数据包是否实际进入网络?我尝试了以下两种解决方案:

  1. 插入socket.getInputStream().read()250ms超时的附加操作.这会强制在删除连接时失败的读取操作,否则会挂起250ms.

  2. 将TCP发送缓冲区大小(例如Socket.setSendBufferSize())设置为消息二进制大小.

这两种方法都有效,但它们会严重降低服务质量; 吞吐量最多从100条消息/秒到大约10条消息/秒.

有什么建议?

更新:

受到多个答案的质疑,质疑所描述的可能性.我构建了我所描述的行为的"单元"测试.查看Gist 273786上的单位案例.

两个单元测试都有两个线程,一个服务器和一个客户端.客户端发送数据时服务器关闭,而不会抛出IOException.这是主要方法:

public static void main(String[] args) throws Throwable {
    final int PORT = 8005;
    final int FIRST_BUF_SIZE = 5;

    final Throwable[] errors = new Throwable[1];
    final Semaphore serverClosing = new Semaphore(0);
    final Semaphore messageFlushed = …
Run Code Online (Sandbox Code Playgroud)

java sockets networking apple-push-notifications

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