繁体   English   中英

通过套接字发送文件(服务器端带有线程)-不起作用

[英]Send file over socket (with threading on server-side) - not working

我有一个客户端服务器程序。 客户端程序将文件发送到服务器,服务器接收到该文件。 我的问题是,该文件实际上没有在服务器上接收...我没有在服务器目录中创建file.txt,但是它是空的...(是的,我确定ne中的file.txt客户目录不为空;))我认为问题在于Client.java中的while循环,因为它从不尴尬。

为了将来,我现在在服务器端实现每个接收文件一个线程。

客户端程序:

   package controller;

   public class Main {

       public static void main(String[] args) {
           new Controller();
    }

}

-

    package controller;

    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.PrintStream;
    import java.net.Socket;
    import java.net.UnknownHostException;



    public class Controller {

        public Controller() {
            try {
                sendFileToServer(); 
            } catch (IOException e) {
                e.printStackTrace();
            }  

        }

        public void sendFileToServer() throws UnknownHostException, IOException {
            Socket socket = null;
            String host = "localhost";

            socket = new Socket(host, 5555);    

            String filename = "file.txt";       
            File file = new File(filename); 

            OutputStream outText = socket.getOutputStream();
            PrintStream outTextP = new PrintStream(outText);
            outTextP.println(filename);

            long filesize = file.length();    
            byte[] bytes = new byte[(int) filesize];        
            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);     

            BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());

            int count;
            System.out.println("Start sending file...");

            while ((count = bis.read(bytes)) > 0) {         
                System.out.println("count: " + count);
                out.write(bytes, 0, count);
            }
            System.out.println("Finish!");

            out.flush();

            out.close();
            fis.close();
            bis.close();
            socket.close();
        }


    }

-

服务器程序:

    import java.io.IOException;


    public class Main {

        public static void main(String[] args) throws IOException {
            new Server();
        }

    }

-

    public class Server {

        private ServerSocket serverSocket;

        public Server()  {
            try {
                serverSocket = new ServerSocket(5555);
                waitForClient();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        private void waitForClient() {
            Socket socket = null;

            try {

                while(true) {
                    socket = serverSocket.accept();     
                    Thread thread = new Thread(new Client(socket));
                    thread.start(); 
                }

            } catch (IOException ex) {
                System.out.println("serverSocket.accept() failed!");
            }
        }

    }

-

    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.Socket;

    public class Client implements Runnable{

        private Socket socket;

        public Client(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            receiveFile();   
        }

        private void receiveFile()  {
            try {

                InputStream is = null;
                FileOutputStream fos = null;
                BufferedOutputStream bos = null;
                int bufferSize = 0;

                InputStream outText = socket.getInputStream();      

                // Get filename
                InputStreamReader outTextI = new InputStreamReader(outText);
                BufferedReader inTextB = new BufferedReader(outTextI);
                String dateiname = inTextB.readLine();
                System.out.println("Dateiname: " + dateiname);

                try {
                    is = socket.getInputStream();           

                    bufferSize = socket.getReceiveBufferSize();
                    System.out.println("Buffer size: " + bufferSize);
                } catch (IOException ex) {
                    System.out.println("Can't get socket input stream. ");
                }

                try {
                    fos = new FileOutputStream(dateiname);  
                    bos = new BufferedOutputStream(fos);

                } catch (FileNotFoundException ex) {
                    System.out.println("File not found.");
                }

                byte[] bytes = new byte[bufferSize];

                int count;

                while ((count = is.read(bytes)) > 0) {          
                    bos.write(bytes, 0, count);                 
                    System.out.println("This is never shown!!!");   // In this while-loop the file is normally receiving and written to the directory. But this loop is never embarrassed...                                                                        
                }

                bos.flush();

                bos.close();
                is.close();
                socket.close();
            }catch(IOException e) {
                e.printStackTrace();
            }
        }

    }

当您进行此类传输时,必须记住套接字的关闭关闭之间是有区别的,在您的代码中,您将关闭客户端中的套接字。

因此,让我们看看会发生什么:您填充缓冲区,然后告诉套接字关闭,这将放弃您刚才要求的操作。 关闭时,您告诉套接字“我不会发送更多数据, 而是发送剩下的要发送的内容并关闭”,因此您需要做的是在关闭套接字之前先关闭套接字,以使数据到达。

所以代替这个

out.flush();

out.close();
fis.close();
bis.close();
socket.close();

试试这个

out.flush();

socket.shutdownInput();    // since you only send you may not need to call this
socket.shutdownOutput();   // with this you ensure that the data you "buffered" is sent
socket.close();

通常,如果您想要正常关闭,则即使在服务器上,也应在所有情况下都这样做,因此,如果出现错误,通常所做的事就可以了,因为您无法从错误中恢复,所以只需关闭连接即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM