如何防止InputStream和OutputStream在通过套接字的双向文件传输中相互干扰?

问题描述 投票:0回答:1

我正在尝试使用https://www.rgagnon.com/javadetails/java-0542.html中的代码来创建双向文件传输程序。我试图将代码的接收和发送代码分成各自的方法,并在服务器端调用send然后接收,在客户端调用receive然后发送。如果我仅以自己的方式进行传输,那么它可以工作,但是当我尝试进行一种传输时,使用另一个文件返回,则在最后一次传输完成之前将清除流。

这里是字段和main()类TestServer {

public final static int SOCKET_PORT = 13267;
public final static String FILE_TO_RECEIVED = "D:\\TestFiles\\Client\\CFileReceived.txt";
public final static String FILE_TO_SEND = "D:\\TestFiles\\Client\\SFileToBeSent.txt";
// file size temporary hard coded should bigger than the file to be downloaded
public final static int FILE_SIZE = 6022386;

private static ServerSocket servsock = null; // used in main
private static Socket sock = null; // used in main

public static FileOutputStream fos = null; // used in receive
public static BufferedOutputStream bos = null; // used in receive
public static InputStream is = null; // used in receive
public static int bytesRead; // used in receive
public static int current = 0; // used in receive

private static FileInputStream fis = null; // used in send
private static BufferedInputStream bis = null; // used in send
private static OutputStream os = null; // used in send

private static InputStreamReader isr;
private static BufferedReader br;

public static void main(String[] args) throws IOException, InterruptedException {

    try {

        servsock = new ServerSocket(SOCKET_PORT); // creates servsock with socket port
        while (true) {

            System.out.println("Waiting...");
            try {

                sock = servsock.accept(); // accepts a socket connection
                System.out.println("Accepted connection : " + sock);

                os = sock.getOutputStream(); // sets Output Stream using the sockets output stream
                is = sock.getInputStream(); // get input stream from socket

                control("send");
                control("receive");

            } // end of try
            finally {
                // if any streams or sockets are not null, the close them
                if (bis != null)
                    bis.close();
                if (os != null)
                    os.close();
                if (sock != null)
                    sock.close();
            } // end of finally
        } // end of while
    } // end of try
    finally {

        if (servsock != null)
            servsock.close();
    } // end of finally
} // end of main

这里是字段和main()类TestClient {

public final static int SOCKET_PORT = 13267; // you may change this
public final static String SERVER = "127.0.0.1"; // localhost

// you may change this, I give a different name because i don't want to
// overwrite the one used by server...
public final static String FILE_TO_RECEIVED = "D:\\TestFiles\\Client\\SFileReceived.txt";
public final static String FILE_TO_SEND = "D:\\TestFiles\\Client\\ClientCFileToBeSent.txt";

// file size temporary hard coded should bigger than the file to be downloaded
public final static int FILE_SIZE = 6022386;

public static Socket sock = null; // used in main

public static FileOutputStream fos = null; // used in receive
public static BufferedOutputStream bos = null; // used in receive
public static InputStream is = null; // used in receive
public static int bytesRead; // used in receive
public static int current = 0; // used in receive

private static FileInputStream fis = null; // used in send
private static BufferedInputStream bis = null; // used in send
private static OutputStream os = null; // used in send

private static PrintWriter pw;

public static void main(String[] args) throws IOException {

    try {

        sock = new Socket(SERVER, SOCKET_PORT);
        System.out.println("Connecting...");

        // get input and output from socket
        is = sock.getInputStream(); // get input stream from socket
        os = sock.getOutputStream(); // get output stream from socket

        // receive file
        control("receive");
        control("send");

    } // end of try
    finally {

        if (sock != null)
            sock.close();
    } // end of finally
} // end of main

这是服务器和客户端中的控件,接收和发送方法。

public static void control(String input) throws IOException {

    switch (input) {
    case "send":
        sendFile(FILE_TO_SEND);
        break;

    case "receive":
        receiveFile();
        break;

    case "end":
        break;

    default:

    } // end of switch
} // end of control()

public static void sendFile(String filetosend) throws IOException {

    File myFile = new File(filetosend); // creates a file using file to send path
    byte[] mybytearray = new byte[(int) myFile.length()]; // creates a byte array the size of myFile
    fis = new FileInputStream(myFile); // creates new FIS from myFile
    bis = new BufferedInputStream(fis); // creates BIS with the FIS
    bis.read(mybytearray, 0, mybytearray.length); // copies the BIS byte array into the byte array

    // prints to console filename and size
    System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");

    os.write(mybytearray, 0, mybytearray.length); // copies the byte array into the output stream therefore sending
    // it through the socket
    os.flush(); // flush/clears the output stream
    System.out.println("Done.");
} // end of sendFile()

// ------------------------------------------------

public static void receiveFile() throws IOException {

    byte[] mybytearray = new byte[FILE_SIZE]; // creates byte aray using file size
    fos = new FileOutputStream(FILE_TO_RECEIVED); // creates file from path
    bos = new BufferedOutputStream(fos); // creates BOS from FOS
    bytesRead = is.read(mybytearray, 0, mybytearray.length); // assigns the input stream to
    current = bytesRead; // equals the two integers for comparisons later

    do { // no freaking clue
        bytesRead = is.read(mybytearray, current, (mybytearray.length - current));
        if (bytesRead >= 0)
            current += bytesRead;
    } while (bytesRead > -1);

    bos.write(mybytearray, 0, current); // writes the byte array to the BOS therefore into the file
    bos.flush(); // clears the buffer

    // prints to the console the name and size of file
    System.out.println("File " + FILE_TO_RECEIVED + " downloaded (" + current + " bytes read)");
} // end of receiveFile()

服务器的输出为:等候...接受的连接:套接字[地址= / 127.0.0.1,端口= 62815,本地端口= 13267]发送SFileToBeSent.txt(32字节)做完了Client的输出为:正在连接...

SFileReceived.txt和CFileReceived.txt均被创建,但其中没有任何内容。我对任何类型的InputStream和OutputStream都是新手,那么程序会出什么问题?非常感谢您的任何想法。

java sockets client inputstream outputstream
1个回答
0
投票

[首先,您的receiveFile方法应在循环中读取输入并写入输出。其次,请在完成后关闭文件,否则可能会导致资源泄漏。

公共静态无效的receiveFile()抛出IOException {

byte[] mybytearray = new byte[FILE_SIZE]; // creates byte aray using file size
fos = new FileOutputStream(FILE_TO_RECEIVED); // creates file from path
bos = new BufferedOutputStream(fos); // creates BOS from FOS
int current = 0; // equals the two integers for comparisons later

try {
    while ((bytesRead = is.read(mybytearray)) != -1) {
        bos.write(mybytearray, 0, bytesRead );
        current += bytesRead;
    }
    bos.flush(); // clears the buffer
    System.out.println("File " + FILE_TO_RECEIVED + " downloaded (" + current + " bytes read)");
} finally {
  bos.close();
}

}

© www.soinside.com 2019 - 2024. All rights reserved.