我正在进行实验,以了解自己对通过服务器和客户端之间的TCP连接传输任何文件的好奇心
我的项目是“服务器接收文件”和“客户端发送该文件”
但似乎出了问题,客户端可以发送整个文件,服务器端也可以接收整个文件但是在服务器端接收后文件无法打开就像读取时出错了发送它的块
你们可以检查我是否做错了吗
这是我的服务器端代码
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TFServer2 {
private static ServerSocket servSock;
private static int port;
public static void main(String[] args) throws NumberFormatException, IOException{
if(args.length < 1){
port = 1500;
}else{
port = Integer.parseInt(args[0]);
}
servSock = new ServerSocket(port);
int i = 1;
while(true){
System.out.println("Listening connection...");
Socket client = servSock.accept();
System.out.println("Client " + i + "requires connection!");
ClientHandler ch = new ClientHandler(client);
ch.setNumber(i++);
ch.start();
}
}
}
这里是ClientHandler
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
public class ClientHandler extends Thread{
private int i;
private Socket client;
private ObjectInputStream sInt;
private String fileName;
private int file_size;
private File file;
private FileOutputStream outStr;
private BufferedOutputStream bos;
public ClientHandler(Socket client) throws IOException{
this.client = client;
this.sInt = new ObjectInputStream(this.client.getInputStream());
}
public void setNumber(int i){
this.i = i;
}
public void run(){
try {
System.out.println("Client " + i + ": " + client.getInetAddress() + " connected on port " + client.getPort());
//get filename
fileName = (String) sInt.readObject();
String[] str = fileName.split(".");
//get file size
file_size = sInt.readInt();
//open file
file = new File("D:\\practice_java_network\\TransferFileServer\\Download\\" + fileName);
//create file output stream
outStr = new FileOutputStream(file);
//create buffered output
bos = new BufferedOutputStream(outStr);
byte[] buffer = null;
int total_read_len = 0;
//receiving file loop
while( sInt.readBoolean() ){
buffer = (byte[]) sInt.readObject();
total_read_len += buffer.length;
bos.write(buffer);
System.out.println("Receive: " + (float)total_read_len/file_size*100 + "%");
}
//close all connection
bos.close();
outStr.close();
sInt.close();
client.close();
System.out.println("connection with client " + i + " closed");
System.out.println("Done recieving file");
System.out.println("File contained at: " + file.toPath());
return;
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这是客户端的代码
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class TFClientv2 {
private static Socket socket;
private static int port;
private static String host;
private static String fileName;
private static File file;
private static BufferedInputStream bis;
private static ObjectOutputStream sOut;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try{
System.out.println("Args: " + args.length);
//check arguments
if(args.length < 1)
host = "somehost";
else
host = args[0];
System.out.println("Host: " + host);
if(args.length < 2)
port = 1500;
else
port = Integer.parseInt(args[1]);
System.out.println("port: " + port);
if(args.length < 3){
System.out.print("File: ");
fileName = sc.nextLine();
fileName = insert(fileName, '\\');
}else{
fileName = insert(args[2], '\\');
}
//done checking arguments
//test if the file does exist
file = new File(fileName);
if(!file.exists()){
System.out.println("There's no such file!");
System.exit(1);
}
/*
* create input Stream to read file
*/
bis = new BufferedInputStream(new FileInputStream(file));
/*
* connect to host preparing to send the file
* and create get outputStream
*/
System.out.println("Opening connection with host: " + host);
socket = new Socket(host, port);
System.out.println("Connected to host " + socket.getInetAddress());
sOut = new ObjectOutputStream(socket.getOutputStream());
/*
* extract only exact file name(not path)
* and send to server
*/
String[] str = fileName.split("\\\\");
sOut.writeObject(str[str.length-1]);
System.out.println("Prepairing file \"" + str[str.length-1] + "\" to be sent");
/*
* these variables necessary to be used
* for sending file
*/
int file_len = (int) file.length();
int buff_size = 1024;
int bytesRead = 0;
int total_read_len = 0;
byte[] buffer = new byte[buff_size];
int file_len_2 = file_len;
//tell server to know size of the file
sOut.writeInt(file_len);
//This one copy the file in exact size
//begin read and send chunks of file in loop
while( file_len_2 > 0 ){
if( file_len_2 < buff_size ){
buffer = new byte[file_len_2];
bytesRead = bis.read(buffer);
}else{
bytesRead = bis.read(buffer);
}
file_len_2 -= bytesRead;
total_read_len += bytesRead;
sOut.writeBoolean(true);
sOut.writeObject(buffer);
System.out.println("Sent: " + (float)total_read_len/file_len*100 + "%");
}
//This one copy a little bit bigger
/*while( (bytesRead = bis.read(buffer)) != -1 ){
total_read_len += bytesRead;
sOut.writeBoolean(true);
sOut.writeObject(buffer);
System.out.println("Sent: " + (float)total_read_len/file_len*100 + "%");
}*/
sOut.writeBoolean(false);
System.out.println("Done sending file!");
//close all connection
bis.close();
sOut.close();
socket.close();
}catch(NumberFormatException nfe){
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String insert(String str, char ch){
StringBuilder strBuff = new StringBuilder(str);
int c = 0;
for(int i = 0 ; i < str.length() ; i++){
if(str.charAt(i) == ch){
strBuff.insert(i+c, ch);
c++;
}
}
return strBuff.toString();
}
}
答案 0 :(得分:-1)
客户端在每次sOut.flush()
操作后写sOut.write()
。
当您在stream
中写信时,您需要flush
stream
,以便读者可以从stream
获取数据。