我打开一个TCP套接字并将其连接到网络上其他位置的另一个套接字.然后,我可以成功发送和接收数据.我有一个计时器,每秒钟向套接字发送一些东西.
然后,我通过强行断开连接(在这种情况下拉出以太网电缆)粗暴地中断连接.我的套接字仍然报告它每秒都成功写出数据.这持续大约1小时30分钟,最终给出写入错误.
什么指定套接字最终接受另一端的超时消失了?它是操作系统(Ubuntu 11.04),它来自TCP/IP规范,还是套接字配置选项?
我正在研究以下基本的Java套接字代码(源代码).这是一个Knock-Knock-Joke客户端/服务器应用程序.
在客户端中,我们像往常一样设置套接字:
try {
kkSocket = new Socket("localhost", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch( UnknownHostException uhe ){ /*...more error catching */
Run Code Online (Sandbox Code Playgroud)
然后,我们只是读取和写入服务器:
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("bye."))
break;
fromUser = stdIn.readLine();
if (fromUser != null){
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
Run Code Online (Sandbox Code Playgroud)
在服务器上,我们有相应的代码,以获得笑话的妙语.
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = …Run Code Online (Sandbox Code Playgroud) 我正在开发一个服务器,通过TCP/IP托管第三方设备,并且遇到突然的连接丢失(设备通过蜂窝连接).我需要找到一种方法来检测断开连接,而无需将数据写入设备本身.
我已经看过使用TCP keepalive功能,但Java似乎不允许任何调整keepalive操作的时间.
这样做有什么建议的方法吗?
我的简化套接字代码如下:
public class Test2Socket {
public static void main(String[] args) {
try {
ServerSocket skt = new ServerSocket(1111);
Socket clientSocket = skt.accept();
clientSocket.setKeepAlive(true);
System.out.println("Connected..");
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while((inputLine = input.readLine()) != null)
{
System.out.println(inputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
任何反馈将不胜感激.
我想降低一个Socket的TCP保持活动时间,从2小时开始到10分钟左右.我可以使用socket.setKeepAlive(true)使用keepalive,但是如何控制keepalive数据包发送之前的时间?
看起来我可以这样做,如果我使用NDK,但我想将此代码分发为jar,所以这对我来说并不理想.
这是我的配置:
httpClient = new OkHttpClient.Builder()
.callTimeout(Duration.ofSeconds(60))
.connectTimeout(Duration.ofSeconds(60))
.readTimeout(Duration.ofSeconds(60))
.writeTimeout(Duration.ofSeconds(60))
.build();
Run Code Online (Sandbox Code Playgroud)
我有一个使用此客户端的多线程进程。运行几秒钟后,我得到:
java.net.SocketTimeoutException:
在okio.Okio $ 4.newTimeoutException(Okio.java:232)
在okio.AsyncTimeout.exit(AsyncTimeout.java:286)
在okio.AsyncTimeout $ 2.read(AsyncTimeout.java:241)
在.RealBufferedSource.indexOf(RealBufferedSource.java:358)
如果将超时配置为60秒怎么办?
编辑:
即使添加自定义调度程序也无济于事:
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(Integer.MAX_VALUE);
dispatcher.setMaxRequestsPerHost(Integer.MAX_VALUE);
Run Code Online (Sandbox Code Playgroud)
技术细节:
与我所说的相反,我在Linux机器上同时运行客户端和服务器:
客户端计算机:net.ipv4.tcp_keepalive_time = 7200
服务器计算机:net.ipv4.tcp_keepalive_time = 7200
在C/Linux中,可以轻松地为每个KEEPALIVE tcp连接单独设置有关这些套接字选项的不同值.
TCP_KEEPCNT(自Linux 2.4起)TCP在丢弃连接之前应发送的最大keepalive探测数.此选项不应用于可移植的代码中.
TCP_KEEPIDLE(自Linux 2.4起)如果在此套接字上设置了套接字选项SO_KEEPALIVE,则在TCP开始发送keepalive探测之前,连接需要保持空闲的时间(以秒为单位).此选项不应用于可移植的代码中.
TCP_KEEPINTVL(自Linux 2.4起)各个keepalive探测之间的时间(以秒为单位).此选项不应用于可移植的代码中.
在netty或java中,如何为socket设置三个socket选项?我知道没有可移植的方法来解决它,但只有在Linux中,我可以设置这些套接字选项吗?