我们在java(windows / server上的eclipse)和android app(android studio / client)之间创建了一个服务器客户端关系。通信似乎很好,但有时连接速度非常慢,直到应用程序和服务器不再响应。然而,没有给出真正的错误,并且在连接顺利或缓慢时没有模式。
我们在堆栈处寻找答案,但我们只能找到有关输出和输入流的答案。但是,一旦建立连接(serverSocket.accept()),程序就可以正常运行,并且可以超快速地创建流。因此我们认为问题在于服务器端创建套接字。该程序最多只能处理30个客户端,并且唯一的通信存在字符串(因此没有大量的数据传输)。
注意:当一个连接接受缓慢时,来自客户端的下一个upcomming请求必须等待。当它们轮到它们时,它们会再次快速地或者慢慢被服务器接受。所有连接都在端口8080上进行。
我们的服务器和客户端的代码如下所示,是否有人知道为什么连接(在某些随机时间)这么慢?
SERVER:
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"
}
CLIENT(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();
}
非常感谢!
答案 0 :(得分:0)
您应该将主服务器循环(while(keepGoing)...)提取到run方法中,并使服务器实现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....
}
}
我希望你得到我想说的话,否则只是评论,我会升级我的例子;)
答案 1 :(得分:0)
在开始循环之前,您应该在ClientThread
方法的run()
中创建流。不在构造函数中。否则你在接受线程中进行I / O操作,这会减慢它的速度。
我不知道为什么你在客户端创建一个线程只是为了立即加入它。
答案 2 :(得分:0)
原来我们遇到了路由器问题。将所有平板电脑和计算机连接到本地热点时,它运行得非常流畅!坦克大家帮忙:D
答案 3 :(得分:-1)
编辑:尝试这里提到的BufferedStreamReader:Java socket performance bottleneck: where?
而不是:
sOutput = new ObjectOutputStream(socket.getOutputStream());
使用:
sOutput = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
并用以下内容冲洗:
sOutput.flush();
对于InputStream也一样,使用BufferedInputStream。