简体   繁体   English

Java服务器套接字数据输入流读取超时

[英]Java server socket data input stream read timeout

I am having java server and just one client at the time. 我当时有Java服务器,只有一个客户端。

  • client connects and sends card ID (blocking read on server side is suitable, because only 1 client at the time) 客户端连接并发送卡ID(阻止在服务器端读取是合适的,因为此时只有1个客户端)
  • if card doesn't exist in database it just sends back 0 and close the socket (no problem) 如果卡在数据库中不存在,则仅发送回0并关闭套接字(没问题)
  • if card does exist sends back 1 如果卡确实存在,则发回1
  • now client has to send PIN to the server, but there has to be some timeout, let's say 10s. 现在客户端必须将PIN发送到服务器,但是必须有一些超时,例如10s。 Here i cannot use blocking read, what should i do? 在这里我不能使用阻塞读取,该怎么办? Socket setSoTimeout is not an option, because first read is blocking but second one should not be. 套接字setSoTimeout不是一个选项,因为第一次读取正在阻止,但第二次则不应。

My advice is to create a ExecutorService and start a thread with it. 我的建议是创建一个ExecutorService并启动一个线程。

There is a example here : http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html 这里有一个示例: http : //docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html

The correct (but not the easiest) way to to this is to use java.nio.channels.SocketChannel . 正确的方法(但不是最简单的方法)是使用java.nio.channels.SocketChannel It's read method reads into a ByteBuffer . 它的read方法读入ByteBuffer You combine it with a java.nio.channels.Selector to read from multiple sockets without blocking (the selector helps you find out which one has data available) but in your case you may simply be happy with the SocketChannel . 您可以将其与java.nio.channels.Selector结合使用,以不受阻塞地从多个套接字读取(选择器可帮助您找到哪个套接字有可用数据),但对于您而言,您可能对SocketChannel感到满意。

It is a lot harder to use though - there is no InputStream and you need to manage the ByteBuffer . 但是,使用起来要困难得多-没有InputStream ,您需要管理ByteBuffer

Another alternative is to start a watchdog Thread that sleeps for the duration of your timeout and then closes the Socket if the client hasn't sent the PIN yet. 另一种选择是启动一个监视程序Thread ,该Thread在超时期间一直处于休眠状态,如果客户端尚未发送PIN,则关闭Socket Closing the socket will interrupt a blocked reader. 关闭插槽将中断读取器的阻塞。

Some older questions to help you with the SocketChannel if you want to go that way: 如果您想通过一些更老的问题来帮助您使用SocketChannel,请执行以下操作:

The server should always use a read timeout. 服务器应始终使用读取超时。 You can vary it after the first request and response. 您可以在第一次请求和响应后更改它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM