gpt4 book ai didi

Java BufferedOutputStream.flush() 不刷新

转载 作者:行者123 更新时间:2023-11-30 02:13:35 27 4
gpt4 key购买 nike

我试图在两端使用 BufferedOutputStream 和 BufferedInputStream 将文件从“服务器”发送到“客户端”。问题是,虽然我在每次写入(右侧)时刷新()服务器上的 BufferedOutputStream,但每刷新一次(左侧),数据就会到达客户端套接字。 program output

正如您所看到的,上面的文件发送得很好,但是如果我使用不同的文件或不同的缓冲区大小,如下所示......

program output fail

...它“坏了”。客户端上的读取被阻止,因为流中没有任何内容,而且应该有。这整件事让我很困惑,显然我错过了一些东西。这是我的代码:

客户端

import java.io.*;
import java.net.*;
import java.util.Scanner;
import java.lang.Math.*;

/**
* Client application which allows the user to connect with server
* and execute simple file transfers.
*
*/
public class Client
{
private BufferedReader textFromSocket;
private PrintWriter textToSocket;
private BufferedInputStream fileFromSocket;
private BufferedOutputStream fileToSocket;

private Socket connection;

private static final int port = 8888;
private static final String host = "localhost";
private static final String filesFolder = "client/clientFiles/";

/**
* Initializes all the streams and the socket
*
* @throws IOException
*/
public Client() throws IOException {

// Try to open up a connection with cslin152, port number 4242. If cslin152 is unavailable,
// run the this on the same machine as the client, and use the hostname host.
connection = new Socket( host, port);

// Buffer the reading stream for performance.
textFromSocket = new BufferedReader( new InputStreamReader( connection.getInputStream()));

// Writing stream
textToSocket = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(connection.getOutputStream())), true);

// Data input (incoming) stream
fileFromSocket = new BufferedInputStream( new DataInputStream(connection.getInputStream()),8*1024);

// Data output (outgoing) stream
fileToSocket = new BufferedOutputStream( new DataOutputStream(connection.getOutputStream()));
}

/**
* Sends a request to server
*
* @param cmd request to send
* @throws IOException
*/
public void askServer(String cmd) throws IOException {
if (cmd != null) {
// write to this
textToSocket.println(cmd);
}

String[] command = cmd.split(" ");
switch (command[0]) {
case "list":
this.readList();
break;
case "get":
if (command.length < 2){
System.out.println("Filename not specified");
}else{
this.getFile(command[1]);
}
break;
case "put":
if (command.length < 2){
System.out.println("Filename not specified");
}else{
this.putFile(command[1]);
}
break;
case "bye":
this.byeBye();
break;
default:
System.out.println(textFromSocket.readLine());
break;
}
}

/**
* Executes client-side commands for "list" command
* "list" command, lists all files available on the server
*/
public void readList(){
try {
String line;
while ( !(line = textFromSocket.readLine()).equals("")) {
System.out.println(line);
}
}
catch (IOException e) {
e.printStackTrace();
}
}

/**
* Executes client-side commands for "get" command
* "get" command, downloads a file from server
*
* @param filename the name of the file where data will be saved
*/
public void getFile(String fileName) throws IOException {
File downloadFile = new File(filesFolder, fileName);
try (FileOutputStream fos = new FileOutputStream(downloadFile)) {
copy(fileFromSocket, fos);
fos.flush();
}
}

public long copy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[8 * 1024];
long total = 0L;
while (true) {
int read = in.read(buffer);
if (read < 0) {
break;
}
out.write(buffer, 0, read);
total += read;
}
return total;
}


/**
* Executes client-side commands for "put" command
* "put" command, uploads a file to server
*
* @param filename the name of the file to upload
*/
public void putFile(String filename){

File sendFile = new File(filesFolder + filename);
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sendFile));
int fileSize = (int)sendFile.length();
if (sendFile.exists()) {
textToSocket.println(fileSize);
byte[] myBuffer = new byte[fileSize];
bis.read(myBuffer, 0, fileSize);
fileToSocket.write(myBuffer);
fileToSocket.flush();
bis.close();
}else {
System.out.println("Error: File not found");
}
}
catch (FileNotFoundException e) {
System.out.println("Error: File doesn't exist");
}
catch (IOException e){
System.out.println("Error: Couldn't read the file");
}

}

/**
* Closes all the streams, connection and terminates the client
*/
public void byeBye(){
try {
connection.close();
fileFromSocket.close();
fileToSocket.close();
textToSocket.close();
textFromSocket.close();
}
catch (IOException e) {
e.printStackTrace();
}
System.exit(0);
}

/**
* Connects with the server and continuously scans for user input
*
*/
public static void main(String[] args)
{
Client client = null;
Scanner keyboardInput = new Scanner(System.in);

while (client == null){
try {
client = new Client();
System.out.println("Connected to server at : "+ host +":"+ port);
}
catch (IOException e) {
System.out.println("ERROR: Couldn't connect to server, press ENTER to try again");
// Wait for ENTER
keyboardInput.nextLine();
}
}
while (true) {
System.out.printf("client>");
String cmd = keyboardInput.nextLine();
try {
client.askServer(cmd);
}
catch (IOException e) {
System.out.println("Error: Server didn't reply");
}

}
}
}

每个线程(连接的客户端)CLIENT_HANDLER

import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* Client handler application which is run as a separate thread for each connected client
*
*/

public class ClientHandler extends Thread
{
private BufferedReader textFromSocket;
private PrintWriter textToSocket;

private BufferedInputStream fileFromSocket;
private BufferedOutputStream fileToSocket;

private Socket connection;

private static final String filesFolder = "server/serverFiles/";
private static final String logFile = "server/log.txt";

/**
* Initializes all the streams and the socket
*
* @throws IOException
*/

public ClientHandler(Socket client){
try {
connection = client;

// Buffer the reading stream for performance.
textFromSocket = new BufferedReader( new InputStreamReader( connection.getInputStream()));

// Writing stream
textToSocket = new PrintWriter( new BufferedWriter( new OutputStreamWriter(connection.getOutputStream())), true);

// Data input (incoming) stream
fileFromSocket = new BufferedInputStream( new DataInputStream(connection.getInputStream()));

// Data output (outgoing) stream
fileToSocket = new BufferedOutputStream( new DataOutputStream(connection.getOutputStream()),8*1024);
}
catch( IOException e )
{
System.out.println( e );
}
}

/**
* Reads a request from client
*
* @return client request
*/

public String getLine(){
try {
return textFromSocket.readLine();
}
catch (IOException e) {
System.out.println("error: Couldn't read from client (Connection Lost)");
return null;
}
}

/**
* Executes server-side commands for "list" command
* "list" command, lists all files available on the server
*/
public void list(){
File serverDir = new File(filesFolder);
File[] fileList = serverDir.listFiles();

for (int i=0;i<fileList.length;i++){
textToSocket.println(fileList[i].getName());
}
textToSocket.println("");
textToSocket.flush();
}

/**
* Executes server-side commands for "get" command
* "get" command, downloads a file from server
*
* @param filename the name of the file to be sent to client
*/
public void get(String filename) throws IOException {
File fileToSend = new File(filesFolder, filename);
try (FileInputStream in = new FileInputStream(fileToSend)) {
copy(in, fileToSocket);
fileToSocket.flush();
}
}

public long copy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[8 * 1024];
long total = 0L;
while (true) {
int read = in.read(buffer);
if (read < 0) {
break;
}
out.write(buffer, 0, read);
total += read;
}
return total;
}

/**
* Executes client-side commands for "put" command
* "put" command, uploads a file to server
*
* @param filename the name of the file to be received from client
*/
public void put(String filename){
try{
String text = textFromSocket.readLine();
if (text.indexOf("ERROR") == -1) {
int fileSize = Integer.parseInt(text);
File downloadFile = new File(filesFolder + filename);
FileOutputStream fos = new FileOutputStream(downloadFile);

byte[] myBuffer = new byte[16 * 1024];
int readBytes = 0;
int currentBytes = 0;
while (readBytes < fileSize) {
currentBytes = fileFromSocket.read(myBuffer, 0, myBuffer.length);
readBytes += currentBytes;
fos.write(myBuffer, 0, currentBytes);
}
fos.close();
System.out.println("File downloaded");
}else{
System.out.println(text);
}
}
catch (IOException e) {
System.out.println("ERROR: Couldn't download\\save the file");
}
}

/**
* Closes all the streams and connection
*/
public void byeBye(){
try {
connection.close();
fileFromSocket.close();
fileToSocket.close();
textToSocket.close();
textFromSocket.close();
}
catch (IOException e) {
e.printStackTrace();
}
}

/**
* Stores a request from client in a log.txt file
* each request is stored in a form: date:time:client IP address:request
*
* @param request the request made by client
*/
public void logRequest(String request){
File file = new File (logFile);
try {
PrintWriter log = new PrintWriter(new BufferedWriter(new FileWriter(file,true)));
// Get all the details
Date today = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy:hh:mm:ss");
String date = dateFormatter.format(today);
String address = connection.getInetAddress().toString();
System.out.println("log: " + date+":"+address+":"+request);
// Save request with details to file
log.println(date + ":" + address + ":" + request);
}
catch (FileNotFoundException e) {
System.out.println("error: log.txt couldn't be created");
}
catch (IOException e){
System.out.println("File writer");
}

}

/**
* Sends an error message to a client
*
* @param text content of the message
*/
public void error(String text){
textToSocket.println("ERROR Server: "+text);
textToSocket.flush();
}

/**
* Continuously reads requests from clients and executes them
*/
public void run() {
String read;
while (( read = (this.getLine())) != null) {
// log the request
this.logRequest(read);
// split command for potential arguments
String[] command = read.split(" ");
if (command.length > 2) {
this.error("Too many arguments");
} else {
switch (command[0]) {
case "list":
this.list();
break;
case "get":
if (command.length < 2){
System.out.printf("Filename not provided");
}else {
try {
this.get(command[1]);
} catch (IOException e) {
e.printStackTrace();
}
}
break;
case "put":
if (command.length < 2){
System.out.printf("Filename not provided");
}else {
this.put(command[1]);
}
break;
case "bye":
this.byeBye();
break;
default:
this.error("illegal command");
break;
}
}
}
}
}

服务器

import java.net.*;
import java.io.*;
import java.util.concurrent.*;

/**
* Server application which allows multiple clients to connect and execute simple file transfers.
*
* Manages a fixed thread pool of maximum 10 threads (connections)
*
*/
public class Server {

private static final int port = 8888;
// As a demonstration, put everything into main(); obviously you would probably want
// to use instance variables and break this up into separate methods for a real application.
public static void main(String[] args) throws IOException {

ServerSocket server = null;
ExecutorService service = null;
File file = new File("server/log.txt");

// Try to open up the listening port
try {
server = new ServerSocket(port);
}
catch (IOException e) {
System.err.println("Could not listen on port: "+ port);
System.exit(-1);
}
System.out.println("Server Running");

// Initialise the executor.
service = Executors.newFixedThreadPool(10);

// Clear/Delete log.txt from last execution
if (file.exists()){
if(file.delete()){
System.out.println("Log cleared");
}else{
System.out.println("Log couldn't be cleared");
}
}else{
System.out.println("Log empty, nothing to clear");
}

// For each new client, submit a new handler to the thread pool.
while( true )
{
Socket client = server.accept();
service.submit( new ClientHandler(client) );
System.out.println("Client connected");
}
}

}

最佳答案

在客户端代码中,您需要在关闭之前调用fos.flush()

顺便说一句,客户端的最小逻辑并不是真正必要的。有更简单的方法可以实现这些目标。

关于Java BufferedOutputStream.flush() 不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49331898/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com