serverSocket.accept() 缓慢或无响应
serverSocket.accept() slow or non-responding
我们在 java(windows/server 上的 eclipse)和 android 应用程序(android studio/client)之间创建了服务器客户端关系。通信似乎很好,但有时连接速度非常慢,直到应用程序和服务器不再响应。然而,没有给出真正的错误,也没有连接何时正常或何时缓慢的模式。
我们在堆栈中寻找答案,但我们只能找到关于输出和输入流的答案。但是,一旦建立连接 (serverSocket.accept()),程序运行良好并且流的创建速度非常快。因此我们认为问题在于服务器端创建套接字。该程序最多只需要处理 30 个客户端,并且唯一的通信存在字符串(因此没有大量的数据传输)。
注意:当一个连接接受很慢时,客户端的下一个上行请求必须等待。轮到他们时,他们再次随机快速或缓慢地被服务器接受。所有连接都在端口 8080 上建立。
我们的服务器和客户端的代码如下,有人知道为什么连接(在某些随机时间)这么慢吗?
服务器:
public void run() {
keepGoing = true;
try {
serverSocket = new ServerSocket(port);
while (keepGoing) {
display("Server waiting for Clients on port " + port + ".");
Socket socket = serverSocket.accept(); //<---our problem
if (!keepGoing) break;
ClientThread t = new ClientThread(socket, this); //<---program doesnt reach this code when it is slow. One client thread exists for each connection.
}catch (IOException e) {
String msg = sdf.format(new Date())
+ " Exception on new ServerSocket: " + e + "\n";
display(msg);
}
}
客户端线程代码:(如果慢则未达到)
public ClientThread(Socket socket, Server s) {
this.server = s;
this.socket = socket;
System.out.println("Thread trying to create Object Input/Output Streams");
try {
// make streams
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
// read user account info
String input = (String) sInput.readObject();
String[] accountInfo = input.split(";");
username = accountInfo[0];
password = accountInfo[1];
} "catch all problems"
}
客户(android)
Thread connect = new Thread(new Runnable() {
@Override
public void run()
{
try
{
socket = new Socket(ip.getText().toString(), portNr);
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
}
catch (UnknownHostException e ){
e.printStackTrace();
} catch(IOException e ){
e.printStackTrace();
}
"sending account information"
}
});
connect.start();
try {
connect.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
非常感谢!
编辑:试试这里提到的 BufferedStreamReader:Java socket performance bottleneck: where?
而不是:
sOutput = new ObjectOutputStream(socket.getOutputStream());
使用:
sOutput = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
并用以下方法冲洗它:
sOutput.flush();
同样适用于 InputStream,使用 BufferedInputStream。
您应该将主服务器循环 (while(keepGoing)...) 提取到 运行 方法中,并使服务器实现 Runnabel 接口。然后创建一个新的线程并启动它。
示例:
public class Server implements Runnable{
private Thread thread;
public Server(){
thread = new Thread(this);
thread.start(); //I would create start() and stop() methods but for simplicity I just use thread.start()
}
@Override
public void run(){
//while....
}
}
我希望你明白我想说的,否则请评论,我会升级我的例子;)
在开始循环之前,您应该在 run()
方法中的 ClientThread
中创建流。不在构造函数中。否则你在接受线程中做 I/O,这会减慢它的速度。
我不知道你为什么要在客户端中创建一个线程,然后立即加入它。
原来我们遇到了路由器问题。将所有平板电脑和计算机连接到本地热点时 运行 超级流畅!坦克大家的帮助 :D
我们在 java(windows/server 上的 eclipse)和 android 应用程序(android studio/client)之间创建了服务器客户端关系。通信似乎很好,但有时连接速度非常慢,直到应用程序和服务器不再响应。然而,没有给出真正的错误,也没有连接何时正常或何时缓慢的模式。
我们在堆栈中寻找答案,但我们只能找到关于输出和输入流的答案。但是,一旦建立连接 (serverSocket.accept()),程序运行良好并且流的创建速度非常快。因此我们认为问题在于服务器端创建套接字。该程序最多只需要处理 30 个客户端,并且唯一的通信存在字符串(因此没有大量的数据传输)。
注意:当一个连接接受很慢时,客户端的下一个上行请求必须等待。轮到他们时,他们再次随机快速或缓慢地被服务器接受。所有连接都在端口 8080 上建立。
我们的服务器和客户端的代码如下,有人知道为什么连接(在某些随机时间)这么慢吗?
服务器:
public void run() {
keepGoing = true;
try {
serverSocket = new ServerSocket(port);
while (keepGoing) {
display("Server waiting for Clients on port " + port + ".");
Socket socket = serverSocket.accept(); //<---our problem
if (!keepGoing) break;
ClientThread t = new ClientThread(socket, this); //<---program doesnt reach this code when it is slow. One client thread exists for each connection.
}catch (IOException e) {
String msg = sdf.format(new Date())
+ " Exception on new ServerSocket: " + e + "\n";
display(msg);
}
}
客户端线程代码:(如果慢则未达到)
public ClientThread(Socket socket, Server s) {
this.server = s;
this.socket = socket;
System.out.println("Thread trying to create Object Input/Output Streams");
try {
// make streams
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
// read user account info
String input = (String) sInput.readObject();
String[] accountInfo = input.split(";");
username = accountInfo[0];
password = accountInfo[1];
} "catch all problems"
}
客户(android)
Thread connect = new Thread(new Runnable() {
@Override
public void run()
{
try
{
socket = new Socket(ip.getText().toString(), portNr);
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
}
catch (UnknownHostException e ){
e.printStackTrace();
} catch(IOException e ){
e.printStackTrace();
}
"sending account information"
}
});
connect.start();
try {
connect.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
非常感谢!
编辑:试试这里提到的 BufferedStreamReader:Java socket performance bottleneck: where?
而不是:
sOutput = new ObjectOutputStream(socket.getOutputStream());
使用:
sOutput = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
并用以下方法冲洗它:
sOutput.flush();
同样适用于 InputStream,使用 BufferedInputStream。
您应该将主服务器循环 (while(keepGoing)...) 提取到 运行 方法中,并使服务器实现 Runnabel 接口。然后创建一个新的线程并启动它。
示例:
public class Server implements Runnable{
private Thread thread;
public Server(){
thread = new Thread(this);
thread.start(); //I would create start() and stop() methods but for simplicity I just use thread.start()
}
@Override
public void run(){
//while....
}
}
我希望你明白我想说的,否则请评论,我会升级我的例子;)
在开始循环之前,您应该在 run()
方法中的 ClientThread
中创建流。不在构造函数中。否则你在接受线程中做 I/O,这会减慢它的速度。
我不知道你为什么要在客户端中创建一个线程,然后立即加入它。
原来我们遇到了路由器问题。将所有平板电脑和计算机连接到本地热点时 运行 超级流畅!坦克大家的帮助 :D