- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图在两端使用 BufferedOutputStream 和 BufferedInputStream 将文件从“服务器”发送到“客户端”。问题是,虽然我在每次写入(右侧)时刷新()服务器上的 BufferedOutputStream,但每刷新一次(左侧),数据就会到达客户端套接字。
正如您所看到的,上面的文件发送得很好,但是如果我使用不同的文件或不同的缓冲区大小,如下所示......
...它“坏了”。客户端上的读取被阻止,因为流中没有任何内容,而且应该有。这整件事让我很困惑,显然我错过了一些东西。这是我的代码:
客户端
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/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!