客户端 - 服务器Java程序在runnig时使用套接字卡住,但在重新布线时工作

时间:2015-05-08 18:17:51

标签: java sockets datainputstream dataoutputstream

我创建了一个简单的实用程序,它实现了服务器和客户端。服务器等待连接,客户端连接,如果服务器上的文件夹中有任何文件 - 它们正在发送给客户端。 我使用 DataInput / OutputStreams - writeUTF / readUTF 在客户端和服务器之间发送消息, writeLong / readLong - 发送文件大小,写/读发送数据。 问题是,当我运行客户端和服务器时 - 发送一个或两个文件后工作卡住了。但是,如果我逐步跟踪IDE中的客户端和服务器,它的工作效果很好,如果我在一个字节中传输缓冲区大小的文件,它也可以工作 - 所以它工作得非常慢,但它不会卡住。 我在客户端使用Eclipse IDE,jdk 1.7,在服务器端使用1.8(也试过1.7),在两个VMWare播放器实例上使用Ubuntu linux和Windows 2003 Server。 我还试图添加Thread.sleep(10000)和flush()任何可能被刷新的东西,甚至添加 socket.setTcpNoDelay(true); 但没有结果。 看起来服务器发送下一个文件名并等待来自客户端的 echo(),但是客户端没有得到它并且卡在 readUTF()上。但是,如果我一步一步地在手动模式下执行它,它可以正常工作。 有任何想法吗?谢谢!

客户来源:

/**
 * Method receives a file from server
 * @param outWriter
 * @param inBufferedReader
 * @param inStream
 * 
 */
private void receiveFileFromServer(DataOutputStream out, DataInputStream in) {
    try {
        String fileName = in.readUTF(); ///<----- stucks here *************
        if (awlConnectionLogger.isInfoEnabled()) {
            awlConnectionLogger.info("Receiving file "+fileName);
        }
        out.writeUTF(fileName);
        out.flush();

        Long fileSize = in.readLong();
        if (awlConnectionLogger.isInfoEnabled()) {
            awlConnectionLogger.info("Filesize "+fileSize);
        }

        out.writeUTF(fileSize.toString());
        out.flush();

        File localFile = new File(fileName);
        FileOutputStream fileOS = new FileOutputStream(localFile);

        byte[] buffer = new byte [2048];
        int bytesRead = 0;

        try {
                for (int i = 0; i<fileSize/buffer.length; i++) {
                bytesRead = in.read(buffer, 0, buffer.length);
                fileOS.write(buffer,0, bytesRead);
                }
                bytesRead = in.read(buffer, 0, (int)(fileSize%buffer.length));
                fileOS.write(buffer,0, bytesRead);
                System.out.println("----------------------- "+bytesRead);
        } catch (IOException e) {
            awlConnectionLogger.error("Error reading file "+fileName);
        };
        fileOS.close();
        if (awlConnectionLogger.isInfoEnabled()) {
            awlConnectionLogger.info("File received.");
        }
    } catch (IOException e) {
        awlConnectionLogger.error("Error reading Stream or socket closed");

    }
}

/**
 * Method sends a @param command to server, waits for answer, then if answer is not null and equals @param answer it logs @param messageOk else @param messageError
 * returns true if everything is ok, else returns false
 * @param outWriter
 * @param inBufferedReader
 * @throws IOException
 */
private boolean sendCommandReceiveAnswer(String command, String answer, String messageOk,String messageError, 
                                        DataOutputStream out, DataInputStream in) throws IOException {
    out.writeUTF(command); //Hello handshake
    out.flush();
    String data = in.readUTF();
    if ((data!=null)&&(data.equals(answer))) {
        if (awlConnectionLogger.isInfoEnabled()) {
            awlConnectionLogger.info(messageOk);
        }
        return true;
    } else {
        awlConnectionLogger.error(messageError);
        return false;
    }
}

/**
 * Try to establish connection with the awl-server according to detected RDP session
 * @param serverIP - ip address of server
 * @param user - username
 */
private void establishConnection(String serverIP, String user) {
    if (awlConnectionLogger.isInfoEnabled()) {
        awlConnectionLogger.info("Trying to establish awl-connection to "+serverIP+" as "+user);
    }
    Integer remoteAwlPort = Integer.parseInt(Config.awlPort); 
    try (Socket awlServerSocket = new Socket(serverIP,remoteAwlPort)) {//Creating autocloseable socket

        this.awlServerSocket = awlServerSocket;
        DataOutputStream out = new DataOutputStream(awlServerSocket.getOutputStream());
        DataInputStream in = new DataInputStream(awlServerSocket.getInputStream());

        if (!sendCommandReceiveAnswer("Hello-awl-client", "Hello-awl-server", "Server hello OK.", 
                                        "Unknown server type. Closing thread.", out, in)) {
            return;
        }; //Hello handshake - return if not successful
        if (!sendCommandReceiveAnswer(user, "User-ok", "Username sent.", "Error sending username. Closing thread.", out, in)) {
            return;
        }   //Sending username
        String hostName = InetAddress.getLocalHost().getHostName(); //Getting client local hostname
        if (!sendCommandReceiveAnswer(hostName, "Hostname-ok", "Local hostname "+hostName+" sent. Ready to receive files.", 
                                        "Error sending hostname. Closing thread.", out, in)) {
            return;
        } //Sending hostname
        awlServerSocket.setTcpNoDelay(true);
        while (isActive) {

            receiveFileFromServer(out, in); //receiving files
            out.writeUTF("Ready");
            out.flush();
        }

    } catch (UnknownHostException e) {
        awlConnectionLogger.error("Error in server IP adress");
    } catch (SocketException e) {
        awlConnectionLogger.error("Problem accessing or creating Socket.");
    } catch (IOException e) {
        awlConnectionLogger.error("General IO Error or Socket closed");
    };
}

服务器来源:

void Echo (DataInputStream in) {
        String echo = null;
        try {
            echo = in.readUTF();
            System.out.println("Echo:"+echo);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void sendToClient (File file, DataOutputStream out, DataInputStream in) {
        System.out.println("Sending file name "+file.getName());
        try {

            out.writeUTF(file.getName());
            out.flush();
            Echo (in); //<--------- stucks here *******************
            out.writeLong(file.length());
            out.flush();
            Echo (in);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Sending file");
        byte [] buffer = new byte [2048];
        FileInputStream fileIS = null;
        try {
            fileIS = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            System.out.println("Error opening file "+file);
            e.printStackTrace();
        }

        try {
            Integer bytesRead;
            int i = 0;
            while((bytesRead=fileIS.read(buffer))>0) {
                out.write(buffer, 0, bytesRead);
            }
            out.flush();
        } catch (IOException e) {
            System.out.println("Error reading file "+file);
            e.printStackTrace();
        };
        System.out.println("File sent.");
        try {
            fileIS.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    public void run () {

        DataOutputStream out = null;
        DataInputStream in = null;
        String data = null;
        String user = null;
        String clientHostName = null;

        try {
            socket.setTcpNoDelay(true);
            out = new DataOutputStream(socket.getOutputStream());
            in = new DataInputStream(socket.getInputStream());
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        System.out.println("New incoming connection thread starded.");

        try {
            data = in.readUTF();
            if (data.equals("Hello-awl-client")) {
                System.out.println("Client hello OK.");
                out.writeUTF("Hello-awl-server");
                out.flush();
                user = in.readUTF();
                System.out.println("User: "+user);
                out.writeUTF("User-ok");
                out.flush();
                clientHostName = in.readUTF();
                System.out.println("Client hostname: "+clientHostName);
                System.out.println("Server hostname: "+InetAddress.getLocalHost().getHostName());
                out.writeUTF("Hostname-ok");
                out.flush();
                System.out.println("Ready to send files.");
                while (isActive) {
                    File file = new File(ServerConfig.pdfFolder+"//"+user);
                    if (!file.isDirectory()) {
                        System.out.println("Error in path to user directory. Exiting thread");
                        return;
                    }
                    File [] files = file.listFiles();
                    for (File fileItem:files) {
                        while (!fileItem.renameTo(fileItem)) {
                            Thread.sleep(1000);
                        }; //waits while file is not busy to send it
                        if (socket.isOutputShutdown()) {
                            out = new DataOutputStream(socket.getOutputStream());
                        }
                        sendToClient (fileItem, out, in);
                        if (fileItem.delete()) {
                            System.out.println("File deleted.");
                        } else {
                            System.out.println("File not deleted.");
                        }
                        data = in.readUTF();
                        System.out.println(data);
                    }
                }
            } else {
                System.out.println("Unknown connection type. Closing thread.");
                return;
            }
        } catch (IOException | InterruptedException e) {
            System.out.println("Connection error or can't sleep thread. Closing thread.");
            return;
        }

    }

0 个答案:

没有答案