基于TCP-java的文件传输
我做这个实验是出于我自己对通过TCP连接在服务器和客户端之间传输任何文件的好奇心 我的项目是“服务器接收文件”和“客户端发送文件” 但似乎出现了问题,客户端可以发送整个文件,服务器端也可以接收整个文件,但在服务器端接收后,文件无法打开,这就像读取和发送其块时出错一样 你能检查一下我是否做错了什么吗 这是我的服务器端代码基于TCP-java的文件传输,java,sockets,file-io,tcp,Java,Sockets,File Io,Tcp,我做这个实验是出于我自己对通过TCP连接在服务器和客户端之间传输任何文件的好奇心 我的项目是“服务器接收文件”和“客户端发送文件” 但似乎出现了问题,客户端可以发送整个文件,服务器端也可以接收整个文件,但在服务器端接收后,文件无法打开,这就像读取和发送其块时出错一样 你能检查一下我是否做错了什么吗 这是我的服务器端代码 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; publi
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();
}
}
}
这是客户端的代码
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("Preparing 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();
}
}
import java.io.BufferedInputStream;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.ObjectOutputStream;
导入java.net.Socket;
导入java.net.UnknownHostException;
导入java.util.Scanner;
公共类TFClientv2{
专用静态插座;
专用静态int端口;
私有静态字符串主机;
私有静态字符串文件名;
私有静态文件;
私有静态缓冲数据流bis;
私有静态ObjectOutputStream sOut;
公共静态void main(字符串[]args){
扫描仪sc=新的扫描仪(System.in);
试一试{
System.out.println(“Args:+Args.length”);
//检查参数
如果(参数长度<1)
host=“somehost”;
其他的
host=args[0];
System.out.println(“主机:“+Host”);
如果(参数长度<2)
端口=1500;
其他的
port=Integer.parseInt(args[1]);
System.out.println(“端口:”+端口);
如果(参数长度<3){
System.out.print(“文件:”);
fileName=sc.nextLine();
fileName=插入(文件名“\\”);
}否则{
fileName=insert(args[2],“\\”);
}
//检查完参数了吗
//测试文件是否存在
文件=新文件(文件名);
如果(!file.exists()){
System.out.println(“没有这样的文件!”);
系统出口(1);
}
/*
*创建输入流以读取文件
*/
bis=新的BufferedInputStream(新文件输入流(文件));
/*
*连接到准备发送文件的主机
*并创建GetOutputStream
*/
System.out.println(“打开与主机的连接:“+host”);
套接字=新套接字(主机、端口);
System.out.println(“连接到主机”+socket.getInetAddress());
sOut=newObjectOutputStream(socket.getOutputStream());
/*
*仅提取精确的文件名(而不是路径)
*并发送到服务器
*/
字符串[]str=fileName.split(“\\\”);
sOut.writeObject(str[str.length-1]);
System.out.println(“准备文件\”+str[str.length-1]+“\”待发送”);
/*
*这些变量是必须使用的
*用于发送文件
*/
int file_len=(int)file.length();
int buff_size=1024;
int字节读取=0;
int total_read_len=0;
byte[]buffer=新字节[buff_size];
int file_len_2=file_len;
//告诉服务器知道文件的大小
sOut.writeInt(文件);
//这一个复制了文件的精确大小
//开始在循环中读取和发送文件块
而(文件长度2>0){
if(文件长度2<缓冲大小){
缓冲区=新字节[文件长度2];
bytesRead=bis.read(缓冲区);
}否则{
bytesRead=bis.read(缓冲区);
}
文件长度2-=字节读取;
总读取长度+=字节读取;
苏特·维特博莱恩(真);
sOut.writeObject(缓冲区);
System.out.println(“发送:”+(浮点)总读取长度/文件长度*100+“%”;
}
//这一份大一点
/*而((bytesRead=bis.read(buffer))!=-1){
总读取长度+=字节读取;
苏特·维特博莱恩(真);
sOut.writeObject(缓冲区);
System.out.println(“发送:”+(浮点)总读取长度/文件长度*100+“%”;
}*/
副书面语(假);
System.out.println(“发送文件完成!”);
//关闭所有连接
二、关闭();
sOut.close();
socket.close();
}捕获(NumberFormatException nfe){
}捕获(未知后异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
公共静态字符串插入(字符串str、字符ch){
StringBuilder strBuff=新的StringBuilder(str);
int c=0;
对于(int i=0;i
在每次sOut.write()
操作后,在客户端写入sOut.flush()
当您在
流中写入时
需要刷新流
,以便读者可以从流
中获取数据文件无法打开
这是什么意思?使用Java还是通过窗口接口?@SotiriosDelimanolis我认为OP意味着文件在传输过程中被破坏了insert()
。转义反斜杠仅适用于字符串文字。任何其他字符串都不需要转义。您不应该在每次写入后刷新,只在传输结束时刷新。
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("Preparing 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();
}
}