serverSocket.accept()缓慢或无响应

时间:2016-06-30 12:59:17

标签: java android performance sockets serversocket

我们在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();
    }

非常感谢!

4 个答案:

答案 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。