Java TCP文件服务器,下载到的文件和原文件大小不一致

问题描述

本人编程新手,要求用java写一个tcp文件服务器,客户端向服务器端发送请求,下载服务器端的文件。我出现的问题是:客户端从服务器端下载到的文件大小不一致,而且下载到的文件也带不开,真诚请教解决办法。//客户端代码import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.BufferedOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.Socket;import java.util.Scanner;public class SendFileClient{ public static void main( String[] args ) throws IOException { // TODO Auto-generated method stub System.out.println( "This is client" ); byte[] buf = new byte[1024]; System.out.println("Please input the Ip Address that you connect");//Create the scanner s1 to let user input the server IP address Scanner s1 = new Scanner(System.in); String ip = s1.nextLine(); System.out.println("Please input the port");//Create the scanner s2 to let user input the server port Scanner s2 = new Scanner(System.in); String portStr = s2.nextLine();//Convert the String portStr to integer int port = Integer.parseInt(portStr); try { // Create the socket Socket s = new Socket(); s.connect ( new InetSocketAddress (ip,port ));//Create the outstream OutputStream os = s.getOutputStream( );//Create the inputstream InputStream is = s.getInputStream( );//Read the buf though the inputstream int len = is.read( buf );//Print out the data by converting it to a String System.out.println( new String( buf, 0, len ) ); System.out.println("Please input the request");//Create scanner s3 to Let the user input the request//The request format has to be:Send filename Scanner s3 = new Scanner(System.in); String req = s3.nextLine(); os.write( req.getBytes( ) );//Read the data to buf though the inputstream int len2 = is.read(buf); String file = new String(buf,0,len2); System.out.println("Wait...");//Create the dataoutputstream for receiving the file DataOutputStream fos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); byte[] buff = new byte[1024];//Receive the file, write it out. int data; while ( -1 != ( data = is.read(buff) ) ) { fos.write( buff ); } System.out.println("nFile has been received successfully.");fos.flush();fos.close();//Close the outputstreamos.flush(); os.close();//Close the inputstream is.close();//Close the socket s.close( ); } catch ( Exception ex ) { ex.printStackTrace(); } } }import java.net.*;import java.io.*;//服务器端代码public class SendFileSocket extends Thread{ /** * @param args */ public static void main( String[] args ) {//Start the server server( ); }//Set the Server port =10000 private static final int PORT = 10000; private Socket s; public SendFileSocket( Socket s ) {//Create the socket object this.s = s; } public void run() { try {//Create the outputstream OutputStream os = s.getOutputStream( );//Create the inputstream InputStream is = s.getInputStream( ); os.write( "Hello,welcome you!".getBytes( ) );//Define the data byte as buf byte[] buf = new byte[10240]; while ( true ) {//Read the buf though the inputstream int len = is.read( buf ); String revStr = new String( buf, 0, len );//Print out the request information from the client System.out.println( "This client wants to "+revStr ); String fileName;//The requet should starts with Send if ( revStr.startsWith( "Send " )) {//Get the file name from the request by using//The method getFileName fileName = getFileName( revStr );//Print out the filename System.out.println( "The file name is :"+fileName);//Write out the filename though the outputstream os.write(fileName.getBytes()); System.out.println("Start to send file " +fileName); String filePath = "C:/"; String file = (filePath+fileName);//Combine the filepath and the filename File fi = new File(file); //Declare a datainputstream DataInputStream fins = new DataInputStream( new BufferedInputStream(new FileInputStream(file))); DataOutputStream ps = new DataOutputStream(s.getOutputStream());//Start to read the data from the file byte[] buff = new byte[10240]; int data; while ( -1 != ( data = fins.read(buff) ) ) { //send the file data to the client ps.write( buff ); } System.out.println("Transfer complete.");ps.flush();ps.close(); break; } else{ System.out.println("Request is wrong"); System.exit(0); } }os.flush();//Close the outputstream os.close( );//Close the inputstream is.close( );//Close the socket s.close( ); } catch ( Exception e ) {//Catch the exception e.printStackTrace( ); } } /* * Function:Get the filename from the request which is sent from the client * param:The request from the client has to start with"Send" * Return: The filename */ private String getFileName( String revStr ) { String fileName; fileName = revStr.substring( 4 ); while ( fileName.startsWith( " " ) ) { fileName = fileName.substring( 1 ); } return fileName; } public static void server() { System.out.println( "This is server" ); try { ServerSocket ss = new ServerSocket( PORT ); int count = 0; while ( true ) {//Create a socket for waiting for the client connect Socket s = ss.accept( );//Count the client and print out count++ ; System.out.println( "This is the " + count + "'st client connetion!" );//Start new thread for this socket new Thread(new SendFileSocket(s)).start(); } } catch ( Exception ex )//Catch the exception { ex.printStackTrace( ); } }}

解决方案

byte[] buff = new byte[1024]; //Receive the file, write it out. int data; while ( -1 != ( data = is.read(buff) ) ) { fos.write( buff,0,data ); } 你这里读到的不一定就是1024,特别是最后一次,不太可能是1024的整数,所以你写出的时候,应该以读到的为准来写出,而不是把整个buff都写出
解决方案二:
建议采用mina或者netty这样的框架来做,会简单很多。
解决方案三:
1.你服务器端while (-1 != (data = fins.read(buff))) {// send the file data to the client// 这种表示将buff 全部发送过去,如果buff 不是满的,会多出限制。// 比如你缓冲区1024*1024 1M,但是你发送1KB 的文件,那么也会导致客户端接受1M的数/据,多出来的默认是0,表示是byte 空的ps.write(buff);// 正确的做法应该是这样,获取多少发多少,两边这样改了就OK了ps.write(buff,0,data);} 2.你客户端也可以采取同样的方式,你也可以采用自带的缓冲流:public BufferedInputStream(InputStream in, int size) 类似的,多看看API 很多的。3.一般网络传文件,最好先发送一段数据,表示文件的大小,先接受,然后在读取文件流,比较大小,确定文件大小是否一致。4.如果文件比较大,或者比较多,你可以采用多线程,但是每个线程你最好都监听一下获取了多少字节,然后再合并到一起,等等措施。自学,可以多尝试哦~.~
解决方案四:
服务器端代码第36行和66行byte[] buf = new byte[10240];10240改为1024

时间: 2024-10-29 06:01:40

Java TCP文件服务器,下载到的文件和原文件大小不一致的相关文章

java 多线程-为什么使用Java多线程下载文件时下载后的文件和服务器端文件大小一模一样但是无法打开

问题描述 为什么使用Java多线程下载文件时下载后的文件和服务器端文件大小一模一样但是无法打开 为什么使用Java多线程下载文件时下载后的文件和服务器端文件大小一模一样但是无法打开?? package com.miuitust.mutilethread; import java.io.File; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; impor

php下载远程大文件(获取远程文件大小)的实例

废话不多说,直接上代码 <?php // 暂不支持断点续传 // $url = 'http://www.mytest.com/debian.iso'; 不知道为何获取本地文件大小为0 $url = 'http://192.168.8.93/download/vm-672/18/0.vmdk'; $file = basename($url); $header = get_headers($url, 1); $size = $header['Content-Length']; $fp = fopen

开源-java上传下载文件服务器选择

问题描述 java上传下载文件服务器选择 目前在做一个ssh的项目,项目中的图片文件比较多, 寻思着再搭建一个文件服务器,可以通过api进行文件上传下载就可以了. 对着方面不太了解,不知道可以采用哪个. 最好是流行,开源的,稍微了解了一下seafile,FASTDfs. 希望熟悉的人能给我推荐一个啊. 解决方案 直接用aws,提供了现成的blob file server

线程-java调用sqlplus下载数据库文件到本地后,如果用java关闭此进程,大神戳进来

问题描述 java调用sqlplus下载数据库文件到本地后,如果用java关闭此进程,大神戳进来 1.用java调用sqlplus,将指定的存储过程下载到本地作为文本文件2.在java读取此本地文件做处理,处理后写1个新的文本文件在本地我将上面2个步骤用2个进程thread1,thread2因为步骤2必须等步骤1结束才能执行,所以我调用thread1.start()thread1.join()以及thread2.start().但是运行结果是每次都只执行出了步骤1,步骤2执行不出来.考虑是否在步

java 通过apache ftp读取大文件或者下载大文件

问题描述 java 通过apache ftp读取大文件或者下载大文件 本人技术短,参照网上各位大侠的帖子写了登录ftp去读取ftp下面文件然后直接存进数据库的代码 ,但是我的代码只能读取一些小的文件,文件大点就报内存溢出.谁可以给个能在ftp上面下载大文件或者能够直接读取ftp服务器上面的大文件然后直接解析存进数据库的代码例子.不胜感激. 解决方案 内存溢出..说明内存方步下文件..ftp取到liu后写入文件吧...ps都内存溢出了..你不可能在内存中解析的..有可能是你jvm内存设置太小所致.

java实现pdf下载文件太慢了怎么办

问题描述 java实现pdf下载文件太慢了怎么办 在用java实现下载pdf文件的时候,文件太大下载不下来怎么办,这些pdf文件还是加密的,在下载的过程还需要解密,所以导致文件下载不下来,怎么解决? 解决方案 撸主 可以试下多线程啊 解决方案二: java实现pdf文件下载Asp.net 实现PDF文件下载ASP.NET 实现PDF文件下载

java实现excel下载(服务器端不生成文件)

问题描述 java实现excel下载(服务器端不生成文件) 语言是java 现在要做的就是点击下载后 直接下载excel文件,但是不能再服务器上生成excel文件 (生成后删除也不行) 数据我已经能取到请问如何操作啊.写在流里还是直接把excel对象写到流里? 我是菜鸟 望大神指点 解决方案 不是,文件是不存在的,知识点击查询的时候 获取 导数据,通过JS 生成excel 或者用通过java后台生成文件放入流中 解决方案二: 点击下载首先你那个文件得存在吧.然后通过流到客户端. 如果流数据你已经

java操作ftp下载文件示例_java

复制代码 代码如下:     /**     *      * JAVA操作 FTP 下载     * 文件下载.     *     */    private void ftpDownload()    {        FTPClient ftpClient = null;        InputStream input = null;        boolean loginFlag = false;        List<String> list = new ArrayList&

如何从Java应用程序动态生成PDF文件

许多应用程序都要求动态生成 PDF 文档.这些应用程序涵盖从生成客户对帐单并通过电子邮件交付的银行到购买特定的 图书章节并以 PDF 格式接收这些图书章节的读者.这个列表不胜枚举.在本文中,我们将使用 iText Java 库生成 PDF 文 档.我们将向您演示一个样例应用程序,以便您可自行完成它并能更好地理解它. 熟悉 iText V5.3.0 版 iText 是一个可从 http://itextpdf.com/ 免费获取的 Java 库.iText 库非常强大,且支持生成 HTML.RTF