Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
客户端-服务器Java程序在运行时使用套接字,但在解除bug时工作_Java_Sockets_Datainputstream_Dataoutputstream - Fatal编程技术网

客户端-服务器Java程序在运行时使用套接字,但在解除bug时工作

客户端-服务器Java程序在运行时使用套接字,但在解除bug时工作,java,sockets,datainputstream,dataoutputstream,Java,Sockets,Datainputstream,Dataoutputstream,我创建了一个简单的实用程序,它实现了服务器和客户端。服务器等待输入连接,客户端连接,若服务器上的文件夹中有任何文件,它们将发送到客户端。 我使用DataInput/OutputStreams-writeUTF/readUTF在客户端和服务器之间发送消息,writeLong/readLong-发送文件大小,write/read发送数据。 问题是,当我在发送一两个文件后同时运行客户端和服务器工作模式时。但是,如果我在IDE中一步一步地跟踪客户机和服务器,它会工作得很好,如果我传输缓冲区大小为一个字节

我创建了一个简单的实用程序,它实现了服务器和客户端。服务器等待输入连接,客户端连接,若服务器上的文件夹中有任何文件,它们将发送到客户端。 我使用DataInput/OutputStreams-writeUTF/readUTF在客户端和服务器之间发送消息,writeLong/readLong-发送文件大小,write/read发送数据。 问题是,当我在发送一两个文件后同时运行客户端和服务器工作模式时。但是,如果我在IDE中一步一步地跟踪客户机和服务器,它会工作得很好,如果我传输缓冲区大小为一个字节的文件,它也会工作——因此它工作得很慢,但不会卡住。 我在客户端使用EclipseIDE,JDK1.7在服务器端使用1.8,在VMWare播放器的两个实例上也尝试了1.7,Ubuntu linux和Windows2003服务器。 我还尝试添加Thread.sleep10000和flush任何可能被刷新的东西,甚至添加了socket.setTcpNoDelaytrue;但没有结果。 看起来服务器发送下一个文件名并等待来自客户机的回音,但客户机并没有得到它并锁定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到缓冲区长度。改用,或者用while循环替换for循环,并实际使用返回的bytesRead。@vanOekel,非常感谢。我花了两周的时间研究这个问题——看起来你关于readFully的建议非常完美!再次感谢你!