我正在开发一款适用于Android的网络服务器,即使我花了好几天时间尝试修复它,但我仍然对这个特定的错误感到满意。我正在尝试从浏览器中读取请求,并且代码在大多数情况下都能正常工作,但是有5%的请求会失败并且它会抛出随机的SocketTimeoutExceptions,甚至不会从Socket中读取单个字符。
我已经用不同的浏览器对它进行了测试,并且它发生在所有这些浏览器上,所以很有可能问题出在我的最后。这是相关的代码,尽可能地删除:
public class ServerThread extends Thread {
private ServerSocket ss = null;
private boolean isRunning;
private ExecutorService threadPool = new ThreadPoolExecutor(2, 12,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
public ServerThread() {
}
public synchronized void run() {
ss = new ServerSocket(8080, 1);
isRunning = true;
while (isRunning) {
Socket clientSocket = null;
try {
if (ss != null) {
clientSocket = ss.accept();
if (isRunning) {
this.threadPool.execute(new HTTPSession(clientSocket));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
和
public class HTTPSession implements Runnable {
private Socket mSocket = null;
public HTTPSession (Socket s) {
mSocket = s;
}
public void run() {
InputStream ips = null;
try {
mSocket.setSoTimeout(15000);
ips = mSocket.getInputStream();
ips.read();
}
catch (Exception e) {
e.printStackTrace();
Log.v("HTTPSession", "Socket connected: " + mSocket.isConnected() + ", Socket closed: " + mSocket.isClosed() + ", InputShutdown: " + mSocket.isInputShutdown());
}
finally {
try { ips.close(); } catch (IOException ioe) { }
try { mSocket.close(); } catch (IOException ioe) { }
}
}
}
所以ServerThread接受连接,HTTPSession尝试从Socket读取,有时它会在15秒后启动SocketTimeoutException。
在这种情况下,catch中Log语句的输出是: Socket connected:true,Socket closed:false,InputShutDown:false
是什么给出的?当然15秒就足够了,主流网络浏览器似乎不太可能不发送任何数据,为什么我不能读它呢?
我很感激有关此问题的任何意见。
答案 0 :(得分:1)
SocketTimeoutException仅表示一件事:在超时期限内没有可用的数据。所以是的,也许你的超时时间太短,是的,浏览器没有在超时期限内发送,或者至少在超时期限内没有到达服务器的套接字接收缓冲区。
我想说服务器端超时15秒有点激进。 30秒到几分钟会更像它。
答案 1 :(得分:0)
我认为这个代码没有任何理由以这种方式失败,除非像你说的那样,浏览器只是没有发送任何内容。您可以将ips.read();
更改为System.out.println(ips.read());
以确保这一点。如果你看到一个字节出现在stdout上,那么浏览器确实发送了一些东西。我的猜测是,在您的完整代码中,您没有正确识别请求的结束并继续等待更多数据。 15秒后,你会超时。但这只是猜测。如果您发布一些演示此问题的代码,则有人可能会给您一个明确的答案。