下面我已经放了一段代码来帮助理解我的问题。我有一个服务器代码,在客户端第一次加载并发送数据包时工作正常。收到第一个数据包后,服务器停留在“接受”状态。
我为此端口配置了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;
}
}
答案 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