簡體   English   中英

無法通過Socket上的BufferedWriter寫入數據

[英]Unable to write data through BufferedWriter on Socket

在將其標記為可能的重復項之前,請先閱讀一遍,因為我找不到任何答案。 我正在學習套接字編程,並使用套接字創建一個非常基本的服務器-客戶端文件傳輸程序。 這是我的服務器模塊:

import java.io.*;
import java.net.*;
import static java.lang.System.out;

public class ServerMain {
    public static void main(String[] args) {
    int PORT=13267;
    ServerSocket servSocket;
    Socket client;
    File source=new File("E:/Styles of Beyond.wav");;
    BufferedInputStream bis;
    BufferedReader br;
    String s="";
    InputStream is;
    byte[] byteBuffer=new byte[10240];
    OutputStream os;
    int count=0;

    try{

        servSocket=new  ServerSocket(PORT);
        out.println("Server running on port: "+PORT+", waiting for client...");
        client=servSocket.accept();
        client.setKeepAlive(true);
        out.println("Client: "+client.getRemoteSocketAddress()+" connected. Sending file...");
        bis=new BufferedInputStream(new FileInputStream(source));
        os=client.getOutputStream();
        is=client.getInputStream();

        while((count=bis.read(byteBuffer))>0){
            os.write(byteBuffer, 0, count);
        }

        out.println("Waiting for confirmation from client...");
        br=new BufferedReader(new InputStreamReader(is));
        if(br.readLine()=="Done")
            out.println("Done.");
        else
            out.println("Couldn't get confirmation from server.");
    }

    catch(Exception e)
    {
        e.printStackTrace();
    }
}
}

和客戶端模塊:

import static java.lang.System.out;
import java.io.*;
import java.net.*;

public class ClientMain {

    public static void main(String[] args) {
        int SERV_PORT=13267;
        Socket server;
        File destination=new File("E:/copy.wav");
        byte[] byteBuffer=new byte[10240];
        InputStream is;
        OutputStream os;
        BufferedWriter bw;
        int count=0;

        try{
            out.println("Tyring to connect to server...");
            server=new Socket("localhost",SERV_PORT);
            out.println("Connected to server: "+server.getRemoteSocketAddress());
            is=server.getInputStream();
            os=server.getOutputStream();
            out.println("Receiving data...");
            BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(destination));

            while((count=is.read(byteBuffer))>0){
                bos.write(byteBuffer, 0, count);
            }
            bw=new BufferedWriter(new OutputStreamWriter(os));
            bw.write("Done");
            bw.newLine();
            out.println("Data successfully written to copy.wav");
        }
        catch(Exception e){
            e.printStackTrace();
        }
}
}

代碼可以正常工作,甚至可以正確創建文件copy.wav,但是在客戶機的操作系統上寫入之后,服務器將停留在“等待客戶機確認...”上,客戶機將停留在“正在接收數據...”上。 我嘗試在客戶端而不是BufferedWriter上使用PrintWriter,還嘗試在os上寫一個字節,然后在服務器端檢查該字節以獲取文件的接收確認,但似乎沒有任何效果,客戶端沒有發送任何內容。 我注意到的一件事是,在服務器上調用is.ready()總是返回false。

如果我刪除所有與在客戶端和服務器上發送和接收文件確認相關的代碼,則客戶端程序將生成SocketException:連接重置,因為現在服務器不再等待客戶端完成其is.read()任務,並且使用os.write()完成寫入后,它將立即關閉連接,這會創建copy.wav並使用小於原始數據的部分數據。 我該如何正確地做這件事?

PS:我知道我還沒有關閉流並正確處理異常,但是這似乎不是問題。

沖洗!

https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html#flush()

致電后:

        bw.write("Done");
        bw.newLine();

操作系統正在等待更多,因此它可以有效地大批量發送數據。

另外,您可以在其上設置TCP_NODELAY,但通常應該讓OS來做,因為在大多數情況下,它比您更了解發送數據的最佳方法。

TCP_NODELAY如何影響連續的write()調用?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM