Java Server套接字停留在接受调用上(Android Client,Java Server)

时间:2010-12-20 11:35:27

标签: java sockets

下面我已经放了一段代码来帮助理解我的问题。我有一个服务器代码,在客户端第一次加载并发送数据包时工作正常。收到第一个数据包后,服务器停留在“接受”状态。

我为此端口配置了wireshark,服务器正在获取这些数据包。我只是想知道为什么接受不会不止一次回来。它让我疯狂。

服务器代码

 public class DAPool implements Runnable {
 private ServerSocket serverSocket;
 private ArrayList<DA> pool;
 private LinkedList<Socket> clientConnQ;
 public DAPool(int newPoolSize, int serverPort) {
  try {
     serverSocket = new ServerSocket(serverPort, 500, InetAddress.getByName("127.0.0.1"));
  } catch (IOException e) {
     e.printStackTrace();
     return;
  }
  poolSize = newPoolSize;
  clientConnQ = new LinkedList<Socket>();
  pool = new ArrayList<DA>(poolSize);
                DA deviceThread;
  for (int threads = 0; threads < poolSize; threads++) {
     deviceThread = new DA();
     connPool.add(deviceThread);
     deviceThread.start();
  }
 }
 public void run() {
    while (true) {
       Socket incomingSocket;
       try {
           incomingSocket = serverSocket.accept();
       } catch (IOException e) {
           e.printStackTrace();
       return;
     }
     insertNewConnToQ(incomingSocket);
  }
 }


 private class DA extends Thread {
  private Socket clientSocket;
  private ObjectInputStream inputObjectStream;
  public DA() { 
  }
  public void run() {
   while (true) {

    while (clientConnQ.isEmpty()) {
     synchronized (clientConnQ) {
      try {
       clientConnQ.wait();
      } catch (InterruptedException ignored) {
       ignored.printStackTrace();
      }
     }
    }
    synchronized (clientConnQ) {
     clientSocket = (Socket) clientConnQ.removeFirst();
     try {
      inputObjectStream = new ObjectInputStream(clientSocket.getInputStream());
     } catch (IOException e) {
      e.printStackTrace();
      return;
     }
        // Do something useful here     
                                    }
    }
   }
  }
 }

客户代码

public class SendQueue extends Thread {
 LinkedList<Message> requestQ;
 Message sendRequest, requestMessage;

 Socket clientSocket;
 OutputStream outputStream;
 ObjectOutputStream objectOutputStream;

 public SendQueue(Socket newClientSocket) {
  requestQ = new LinkedList<Message>();
  clientSocket = newClientSocket;
 }

 public void run() {
  while (true) {
   synchronized (requestQ) {
    while (requestQ.isEmpty()) {
     try {
      requestQ.wait();
     } catch (InterruptedException ignored) {
      ignored.printStackTrace();
     }
    }
    sendRequest = requestQ.removeFirst();
   }
   try {
    outputStream = clientSocket.getOutputStream();
    objectOutputStream = new ObjectOutputStream(outputStream);    
    objectOutputStream.writeObject(sendRequest);
    objectOutputStream.flush();
    outputStream.flush();
   } catch (IOException e) {
    e.printStackTrace();
   } catch (RuntimeException e) {
    e.printStackTrace();
   }
  }
 }

 public int sendRequest(Message message) {
  synchronized (requestQ) {
   requestQ.addLast(message);
   requestQ.notify();
  }
  return 0;
 }
}

3 个答案:

答案 0 :(得分:3)

我没有看到在serverSocket上设置超时。

ServerSocket.accept()是一个阻塞操作,因此它会阻塞,直到发生错误,发生超时或接受连接为止。

尝试

SererSocket.setSOTimeout(10000)

完成后,您似乎也没有关闭流。

答案 1 :(得分:2)

你确定它坚持接听电话吗?你有没有得到一个堆栈跟踪,表明它等待接受?

假设它被卡在别处我想知道是不是因为 clientConnQ 被保存在你的 DA 实例之一中。 synchronized块包含 //在这里做一些有用的事情部分。

我想知道如果你将代码更改为

,它是否可行
synchronized (clientConnQ) {
    clientSocket = (Socket) clientConnQ.removeFirst();
}
try {
    ...

clientConnQ 获得clientSocket后,其他任何实例都无法处理该套接字。

答案 2 :(得分:0)

好的,如果每次我得到一个$,我都会问一个愚蠢的问题:)

到此为止。客户端套接字连接,当服务器收到接受呼叫时。出于某种愚蠢的原因,我正在等待接受来自客户的进一步数据。事实上,我应该等待“流”上的某些事情,然后处理流。我不应该等待接受这种联系。

接受调用以“连接”到套接字,而不是连续接收数据。

感谢您的帮助。你强迫我考虑线程同步,设计,套接字,最后得出解决方案。

很棒的回应人。谢谢。 Siddharth