简体   繁体   English

通过套接字接收文件,TCP连接冻结

[英]Receive file via socket, TCP connection freezes

I have stucked for 4h already with the sockets, the way I am using is is that there is only one application as client and server, once the client connect it is opening the theard with new client and waiting for message . 我已经使用套接字4小时了,我使用的方式是只有一个应用程序作为客户端和服务器,一旦客户端连接它就是用新客户端打开theard 并等待消息

Once the message is send to the server, the client will receive respond, that part is working without any problems. 一旦消息发送到服务器,客户端将收到响应,该部分正常工作没有任何问题。

Part of the Client Theard: 客户Theard的一部分:

while (true)
        {
            InputStreamReader IR = new InputStreamReader(clientSocket.getInputStream());
            BufferedReader BR = new BufferedReader(IR);
            PrintStream PS = new PrintStream(clientSocket.getOutputStream());
            String message = BR.readLine();
            if (message != null)
            {
                System.out.println(clientSocket.getInetAddress() + ":" + clientSocket.getPort() + " has connected."+message);
                if (message.equals("exit"))
                {
                    PS.println("Exiting...");
                    exit();
                }
                else if (message.equals("list"))
                {
                    getList(PS);
                }
                else if ((message.contains("get") && (message.contains(",") && (message.contains(" ")))))
                {
                    String[] spliter = message.split(" ");
                    String[] file = spliter[1].split(",");
                    String file_name = file[0];
                    String file_md5 = file[1];
                    getFile(file_name, file_md5, clientSocket);
                }
            }
            else
            {
                break;
            }

        }

There are 2 messages that the server is supporting, the first one is "list" and the send one command is "get with values". 服务器支持2条消息,第一条是“list”,send one命令是“get with values”。

if client will request command "list" it will run this: There is a "server/client", it is sending request and receive the one line string and it is working without any problem, I am receiving the list of files from the server. 如果客户端将请求命令“列表”它将运行此:有一个“服务器/客户端”,它正在发送请求并接收一行字符串 ,它正在工作没有任何问题,我从服务器接收文件列表。

PrintStream PS = new PrintStream(clientSocket.getOutputStream());
        PS.println("list");
        InputStreamReader IR = new InputStreamReader(clientSocket.getInputStream());
        BufferedReader BR = new BufferedReader(IR);
        String lista_plikow = BR.readLine();
        if ( lista_plikow != null)
        {
            return lista_plikow;
        }

But I have problems to send the files over the sockets using code found on stackoverflow, but the " receiving " is not working, there is my receive function, the loop is always as 0 (even if first bytes length is correct), but the length of the bytes is correct, it is using newly created file but nothing is happening, the file is always on use, and has 0 bytes instead of content of the PS.println. 但我有问题使用stackoverflow上的代码通过套接字发送文件 ,但“ 接收 ”不起作用,有我的接收函数,循环始终为0(即使第一个字节长度正确),但是字节长度是正确的,它使用新创建的文件但没有发生任何事情,文件总是在使用,并且有0个字节而不是PS.println的内容。

PrintStream PS = new PrintStream(clientSocket.getOutputStream());
    PS.println("get "+filename+","+file_md5);
    int bytesRead;
    int current = 0;
    FileOutputStream fos = null;
    BufferedOutputStream bos = null;
    try
    {
        byte [] mybytearray  = new byte [Integer.parseInt(size)];
        InputStream is = clientSocket.getInputStream();
        fos = new FileOutputStream(filename + ".recived");
        bos = new BufferedOutputStream(fos);
        bytesRead = is.read(mybytearray,0,mybytearray.length);
        current = bytesRead;
        System.out.println("X" + bytesRead);
        do {
               bytesRead =
                  is.read(mybytearray, current, (mybytearray.length-current));
            System.out.println(bytesRead + " = " + current + " " + (mybytearray.length-current));

               if(bytesRead >= 0) current += bytesRead;
               System.out.println(bytesRead);
        } while(bytesRead > -1);
        bos.write(mybytearray, 0 , current);
        bos.flush();
        System.out.println("File " + "recived." +filename.replace(":", " ")
            + " downloaded (" + current + " bytes read)");
    }catch (Exception e)
    {
        System.out.println(e.getMessage());
    }

And last part of the scrip the "PS.println("get "+filename+","+file_md5);" 最后一部分是“PS.println(”get“+ filename +”,“+ file_md5);” is doing exactly this one, the sending is working fine: 正是这样做,发送工作正常:

FileInputStream fis = null;
            BufferedInputStream bis = null;
            OutputStream os = null;

            String the_file = TorrentAppGui.folder+"\\"+file_name.replace(":", " ");
             File myFile = new File (the_file);
              byte [] mybytearray  = new byte [(int)myFile.length()];
              fis = new FileInputStream(myFile);
              bis = new BufferedInputStream(fis);
              bis.read(mybytearray,0,mybytearray.length);
              os = clientSocket.getOutputStream();
              System.out.println("Sending " + the_file + "(" + mybytearray.length + " bytes)");
              os.write(mybytearray, 0, mybytearray.length);
              os.flush();
              System.out.println("Done.");

I have no idea why I cannot save the bytes received by the " get " command, do you have any ideas? 我不知道为什么我不能保存“ get ”命令收到的字节,你有什么想法吗? I know that only the "receve" function is not working, because if I looged to the application via telnet I could get the file in the console, but it doesnt reach my target. 我知道只有“receve”功能不起作用,因为如果我通过telnet登陆应用程序,我可以在控制台中获取该文件,但它没有达到我的目标。 See the screen from cli. 从cli看屏幕。

通过telnet连接是工作文件

You can't mixed buffered and unbuffered streams/readers/writers on the same socket. 您不能在同一个套接字上混合使用缓冲和非缓冲的流/读取器/写入器。 You will lose data in the buffers. 您将丢失缓冲区中的数据。 Use the same stream pair for the life of the socket. 在套接字的生命周期中使用相同的流对。 In this case I would use DataInputStream and DataOutputStream , and the readUTF()/writeUTF() methods for the messages and filenames. 在这种情况下,我将使用DataInputStreamDataOutputStream ,以及消息和文件名的readUTF()/writeUTF()方法。 You will also need to send the file length ahead of the file, unless the file is the last thing sent over the connection: otherwise the peer won't know when to stop reading the file and go back and start reading messages again. 您还需要在文件之前发送文件长度,除非该文件是通过连接发送的最后一件事:否则对等体将不知道何时停止读取文件并返回并再次开始阅读消息。

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

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