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

时间:2016-01-09 03:00:53

标签: java sockets tcp

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

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

客户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"发送一个命令是"得到值"。

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

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(即使第一个字节长度是正确的),但字节的长度是正确的,它是使用新创建的文件但没有发生任何事情,文件总是on use,有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());
    }

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

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.");

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

Connection via telnet is working file

1 个答案:

答案 0 :(得分:5)

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