java I / O在服务器端阻塞线程

时间:2010-07-08 11:06:53

标签: java

我正在处理客户端套接字连接。客户端是GPRS硬件设备。我在我的serversocket上接收来自此客户端的请求,然后打开多个线程。我的问题是,当设备/客户端关闭套接字时,我的IO检测到抛出异常但是当我从设备中取出电池同时将请求发送到serversocket时它被阻止而没有抛出任何异常。有人建议我使用setSOTimeout()来阻止线程。

我尝试过Socket.setSOTimeout(int)。但这不符合我的情况。我正确地发送我的代码。

//  inside main class--- 

    public class ServerSocketClass{
    public ServerSocketClass() {
    try{
        serverSocket = new ServerSocket(port);//creating a serversokcet on a port
    System.out.println("Server waiting for client on port " + 
    serverSocket.getLocalPort());
    } catch (Exception e) {
        e.printStackTrace();
    handleExceptions("errorServerSocketOpen.txt", e);
    System.exit(0);
}
try {
    while (true) {
        Socket clientSocket = serverSocket.accept();//accepting the client connection and //creating client socket

        new AcceptConnection(clientSocket);//calling the constructor of other //class to open a new thread
        System.out.println("constructor called.....");
    }
} catch (Exception e) {
    handleExceptions("errorClientSocketOpen.txt", e);
   }
  }
 }
//inside other class---


public class AcceptConnection implements Runnable {
    public AcceptConnection(Socket socket) {
    this.clientSocket = socket;
    if (clientSocket != null) {
        new Thread(this).start();
    }
    public void run() {
        // clientSocket.setSoTimeout(60000);// this is what i added.timeout on each client socket opened in threads
        InputStream inputStream = clientSocket.getInputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
        byte[] mainBuffer = new byte[2048];
        int len = -1, totalLength = 0;
        debugInfo = " GOING TO READ FROM SOCKET.... " + "\n";
        while ((len = inputStream.read(mainBuffer)) > -1) {
            totalLength = len;
        }//end of while
    } }//end of other class

现在我的问题是,当打开多个线程并且我从客户端发送数据时比60秒后它关闭主套接字并停止接收数据。并且发生readtimeout错误。

请帮帮我,告诉我如何实现我的目标。

提前致谢

**

  

@stephen

** 好的斯蒂芬得到了你想说的话......你正确的声明“Well yes ... that's what you told it to do.”可能我无法理解我的问题或者我没有得到setSoTimeout()逻辑,因为我是java的新手。 我想再问一次...... 这就是为每个客户端连接创建一个新客户端套接字并为每个客户端连接打开一个新线程的方法。

    while (true) {
            Socket clientSocket = serverSocket.accept();//accepting the client connection and //creating client socket
                new AcceptConnection(clientSocket);//calling the constructor of other class to open a new thread
            System.out.println("constructor called.....");
        }
public void run() {
            // clientSocket.setSoTimeout(60000);// this is what i added.timeout on each uclient socket opened in threads
........................................
.......................................
}

现在我想说如果我为新的客户端连接打开一个新线程并且我在每个客户端连接对象上单独放置setSoTimeout()然后如果特定线程A在I / O上被阻塞,那么在超时设置之后在setSoTimeout(50000)中,比如50秒,只有线程A应该退出读取并给出异常,而不是同时运行的其他线程说B,C,D。但在我的情况下,超时后所有线程在给出异常后返回事实上,任何新的客户端连接都会产生相同的错误,并且服 我只想要线程A应该给出异常并从read中出来而不影响其他客户端套接字对象(或线程)。

现在我希望我告诉过你关于我的困惑和问题的一切。

请帮帮我,非常感谢。

1 个答案:

答案 0 :(得分:0)

  

现在我的问题是,当打开多个线程并且我从客户端发送数据时比60秒后它关闭主套接字并停止接收数据。并且发生readtimeout错误。

嗯,是的......这就是你告诉它的事情。

正如我想我在回答您之前的问题时所说的那样,无法区分这些情况:

  • 客户端没有数据要发送一段时间。
  • 网络已分区一段时间。
  • 客户已从网络中消失。

您拥有的另一个选择是致电Socket.setKeepAlive()以启用TCP keepalives。这会导致定期执行特殊的“keepalive”握手,以确保TCP / IP连接仍处于活动状态。不幸的是,看起来您不能在Java中设置TCP / IP keepalive间隔。

修改

NIO无济于事。当我在上面说“不能”时...我的意思是在物理上不可能来做到这一点。这是一个类比,可以帮助您理解。

  外在之间唯一的沟通   WoopWoop和世界其他地方是   通过信件。我的朋友每周一次   外WoopWoop(独自生活)的帖子   给我写信给我填写   八卦。上周我没有收到   我朋友的来信。我怎么知道:

     
      
  1. 我的朋友已经去世了,
  2.   
  3. 我的朋友上周没有八卦,
  4.   
  5. 外面的WoopWoop邮政工人已经罢工,或
  6.   
  7. 以上所有?
  8.   

正确答案是我无法分辨。