通过套接字接收文件,TCP连接冻结 [英] Receive file via socket, TCP connection freezes

查看:147
本文介绍了通过套接字接收文件,TCP连接冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用套接字加入了4小时,我使用的方式是只有一个应用程序作为客户端和服务器,一旦客户端连接它就打开了新客户端并等待消息

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.

一旦消息发送到服务器,客户端将收到响应,该部分正常运行。

Once the message is send to the server, the client will receive respond, that part is working without any problems.

部分客户Theard:

Part of the Client 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;
            }

        }

服务器有2条消息支持,第一个是list,send one命令是get with values。

There are 2 messages that the server is supporting, the first one is "list" and the send one command is "get with values".

如果客户端请求命令list,它将运行:
有一个服务器/客户端,它正在发送请求并接收一行字符串,它正在运行没有任何问题,我从服务器接收文件列表。 / p>

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;
        }

但我发送文件时遇到问题使用在stackoverflow上找到的代码的套接字,但接收不起作用,有我的接收函数,循环始终为0(即使第一个字节长度正确),但长度为字节是正确的,它使用新创建的文件但没有发生任何事情,文件总是在使用,并且有0个字节而不是PS.println的内容。

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.

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

最后一部分是PS.println(get+文件名+, + file_md5);正是这样做,发送工作正常:

And last part of the scrip the "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.");

我不知道为什么我无法保存获取命令,你有什么想法吗?
我知道只有receve功能不起作用,因为如果我通过telnet登陆应用程序,我可以在控制台中获取文件,但它没有达到我的目标。请参阅cli的屏幕。

I have no idea why I cannot save the bytes received by the "get" command, do you have any ideas? 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. See the screen from cli.

< img src =https://i.stack.imgur.com/XOumP.pngalt =通过telnet连接工作文件>

推荐答案

您不能在同一个套接字上混合使用缓冲和非缓冲的流/读取器/写入器。您将丢失缓冲区中的数据。在套接字的生命周期中使用相同的流对。在这种情况下,我将使用 DataInputStream DataOutputStream ,以及 readUTF()/ writeUTF( )消息和文件名的方法。您还需要在文件之前发送文件长度,除非该文件是通过连接发送的最后一件事:否则对等体将不知道何时停止读取文件并返回并再次开始阅读消息。

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. 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.

这篇关于通过套接字接收文件,TCP连接冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆