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 outputstream
			os.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( );
        }
    }


}


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

  1.             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都写出

java C/S架构如何实现文件上传到服务器或从服务器下载?

  1. Q
    java C/S架构如何实现文件上传到服务器或从服务器下载?
  2. A
    CS架构实现文件上传下载,首先要考虑采用什么协议进行文件数据的传输。

    如果用HTTP协议,客户端用HTTPClient框架,服务端用Tomcat即可。
    如果用FTP协议,客户端可以用apache的commons.io框架,我记得有FTP客户端的支持,
                   服务端也可以用apache的FTPServer即可。
    如果用自定义的协议,那么,客户端和服务端的所以程序,几乎都要参与编写。
    要考虑协议的具体实现。
    我这里有篇博文,可以供楼主参考一下:

下载80M大小文件时,报system.outOfMemory错误,怎么解决?

  1. Q
    下载80M大小文件时,报system.outOfMemory错误,怎么解决?
  2. A
    描述不清,怎么解决?

安装oracle的RAC需要下载哪几个安装文件?

  1. Q
    有谁知道,安装oracle的RAC需要下载哪几个安装文件?请告知,若有下载地址,更感激不尽!
  2. A
    10g : clusterware + database 
    11g : grid + database 

    10g 的安装程序,官网已经不让下载了。

    http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html

    http://www.oracle.com/technetwork/database/database-technologies/clusterware/downloads/index.html

在servlet中用流进行下载,下载到csv文件里为乱码,但是记事本打开为正常的!!

  1. Q
    在servlet中用流进行下载,下载到csv文件里为乱码,但是记事本打开为正常的!!下面是我的代码的主要部分:
                   //要导入的内容串
                 String conString = userJson.getUserString(domainName, result);
    		
    		response.setContentType("application/x-download");
    		String filedisplay = userJson.createFileName(domainName) + ".csv";//文件名字
    		response.addHeader("Content-Disposition", "attachment;filename="
    				+ filedisplay);
    		try {
    			OutputStream out = response.getOutputStream();
    			OutputStreamWriter write = new OutputStreamWriter(out);
    
    			write.write(conString);
    			write.close();
    
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    

    PS:服务器为tomcat,编码为UTF-8,我试过在改为response.setContentType("application/x-download;charset=utf-8");乱码依旧;
    在服务器后台打印的 System.out.println(conString);也为乱码
    请各位帮忙,我的头都大了,差不多每种编码方式都试过了!!
    能讲下具体原因就更好 了
  2. A
    OutputStreamWriter write = new OutputStreamWriter(out,"utf-8");  

关于 java 读取 存放二进制流 的文件,文件中有int .String.double 等类型数据

  1. Q
    java 读取 存放二进制流 的文件,文件中有int 、String、double 等类型数据

    有几组数据 ,有 int  string 等类型,

    我现在把几个数据 按字节流的形式 写到 硬盘文件里面 。

    然后再读取 这个文件,取出这个文件里面的所有数据。


    如何正确取出里面的数据?

    也就是 byte[] 字节数组里面 有好几组数据,类型有 int String double 等,如何一个一个正确取出来?

  2. A
    RandomAccessFile

求IBM HTTP 8.5 下载地址或文件及插件地址或文件

  1. Q
    求IBM HTTP 8.5 下载地址或文件及插件地址或文件。
    通过安装器下载了一次,时间太长,想要具体文件,自行安装,谢谢。
  2. A
    下载地址:http://www.ibm.com/developerworks/cn/downloads/ws/wasce/

哪里能下载h3crd视频文件?

  1. Q
    有项目需要分析h3crd视频,问哪里能下载到视频文件
  2. A
    H3CRD播放器:
    http://download.csdn.net/detail/happyeinstein/4254235

怎样架设 网上的 服务器下载.jar,.jad文件到手机上

  1. Q
    怎样架设 网上的 服务器下载.jar,.jad文件到手机上
  2. A
    这是我的一个日记:

    西门子的kjava程序的ota下载

    在iis增加如下两个mime:

    jad
    text/vnd.sun.j2me.app-descriptor
    jar
    application/java-archive

    在jad文件里面:
    MIDlet-Version: 1.0.0
    MIDlet-Vendor: Trond Hvoslef
    MIDlet-Jar-URL: http://midlet.org/repository/trondhvoslef/microreader/MicroReader.jar?md=285
    MIDlet-Info-URL: http://home.c2i.net/thvoslef/midlets/MicroReader.html
    MIDlet-1: MicroReader, ,Book
    Manifest-Version: 1.0
    MIDlet-Name: MicroReader
    MIDlet-Jar-Size: 35492
    Charset-map: %ar=Arabic;%kl=Baltic;%cs%cz%hu%ro%hr%sk%sl%sr%pl=Central European;%x1=ISO8859_2;%bg%be%mk%uk%ru=Cyrillic;%x3=Cyrillic (KOI8-R);%el=Greek;%he%iw%ji=Hebrew;%tr=Turkish;%lv%lt=ISO8859_13;%et=ISO8859_15;%*=Western;
    URL-1: eBooks...=http://home.c2i.net/thvoslef/index.txt

    写上正确的jar的url。

    手机访问网址使jad的url的时候,就会提示某某某多大,是否下载。按“是”,就从jar的url下载了。
    加上一些wap页面,就可以实现分类下载之类的功能了。

    moto用的是自己的下载管理器,不知道这种方法是否兼容,待试。

    后面说说我是怎么搞定这件事情的。

    首先,我找到了一个下载midlet的网站,http://midlet.org/wap/
    在我的手机上面访问了这个网址,找了一个软件名称点进去,就出现了“某某某多大,是否下载”的提示。

    于是,我就用openwave的模拟器,打开http回应窗口,然后访问同样的网站,发现在手机出现这个提示的那个地方,模拟器这里所要访问的网址是一个jad文件,而其http头就是上面写的那个了。

    这时候,模拟器就提示出错了,无法继续。于是,从ie里面输入那个jad的url,把那个文件下载下来,在uedit打开,看到了那行jar的。

    重新回到openwave,访问那个jar的url,虽然再次说出错,但是jar的mime也有了。

    我很强啊很强啊。连我都佩服死我自己了。:)

    --------------------

    受到打击了。在http://www.monternet.net/midlet中放上了pis.jad和pis.jar,结果访问pis.jad的时候提示下载,选择是,出现“正在连接……”,随后出现“接收数据”,但是立刻就弹出说“下载失败”,试了几次都一样。:(

    --------------------

    查到原因了。因为3118的浏览器的request头里面的acceptable域里面包含了text/vnd.sun.j2me.app-descriptor,但是没有包含application/java-archive,所以到了下载的时候iis会返回406错误。现在是要摸透iis怎么设置才能避免判断406。

    --------------------

    通过用asp,指定response.contenttype,然后binerywrite jad和jar文件,解决。

    ====================
    欢迎访问http://www.monternet.net/midlet/
    同时,麻烦通过mot的手机测一下这种方法是否兼容

探讨下关于Java生成大量数据的xml文件

  1. Q
    今天在网上搜了一下关于Java生成大量数据的xml文件的方法,并且用SAX来生成1个G的文件,大概用时32秒,不知道这样的速度属于什么样的效率啊,另外大家有什么好的方法生成和解析大xml文件的,可以来探讨一下啊
  2. A
    35M/s 相当高效了
    大文件处理,洋人很多讨论,也有一些方案,
    基本思路都是部分读入,流式处理,记得其中一个是用字节型内存处理的,不过较少用,没记下来
    反正google就是个大bookmark……