A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 坚持525 于 2014-11-4 15:21 编辑

这是源程序,总是上传完的图片是这个样子,求解答,是不是哪块弄错了???
  1. import java.io.BufferedInputStream;
  2. import java.io.BufferedOutputStream;
  3. import java.io.BufferedReader;
  4. import java.io.FileInputStream;
  5. import java.io.InputStream;
  6. import java.io.InputStreamReader;
  7. import java.io.PrintStream;
  8. import java.net.Socket;

  9. /**这是一个多线程TCP向服务器上传文本数据演示
  10. * @author Administrator
  11. *
  12. */
  13. //客户端:
  14. public class ClientPic {

  15.         public static void main(String[] args)throws Exception {
  16.                 Socket s =new Socket("localhost",10002);
  17.                 BufferedInputStream bis=new BufferedInputStream(new FileInputStream("c:/1.jpg"));
  18. //                PrintStream ps= new PrintStream(s.getOutputStream(),true);
  19.                 BufferedOutputStream bos=new BufferedOutputStream(s.getOutputStream());
  20.                 BufferedReader bis2=new BufferedReader(new InputStreamReader(s.getInputStream()));
  21.                 int len;
  22.                 while((len=bis.read())!=-1){
  23.                         bos.write(len);
  24.                 }
  25.                 bos.flush();
  26.                 s.shutdownOutput();
  27.                 String str=bis2.readLine();
  28.                 System.out.println(str);

  29.                 bis.close();
  30.                 s.close();
  31.         }
  32. }
复制代码
  1. import java.io.BufferedInputStream;
  2. import java.io.BufferedOutputStream;
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.OutputStream;
  7. import java.io.PrintWriter;
  8. import java.net.ServerSocket;
  9. import java.net.Socket;

  10. /**服务器端:
  11. * @author Administrator
  12. *
  13. */
  14. class PicThread2 implements Runnable {
  15.         private Socket s;
  16.         PicThread2(Socket s){
  17.                 this.s=s;
  18.         }
  19.         @Override
  20.         public void run() {
  21.                 String ip=s.getInetAddress().getHostAddress();
  22.                 System.out.println(ip+"......connected!");
  23.                 File file=new File("c:/");
  24.                 File f=new File(file,"1.jpg");
  25.                 int count=0;
  26.                 while(f.exists()){
  27.                         f=new File(file,ip+"("+(count++)+")"+".jpg");
  28.                 }
  29.                 try {
  30.                         BufferedInputStream bis =
  31.                                         new BufferedInputStream(s.getInputStream());
  32.                         BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(f));
  33. //                        OutputStream os=new FileOutputStream(f);
  34.                         PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
  35.                         int len;
  36.                         while((len=bis.read())!=-1){
  37. //                                os.write(len);
  38.                                 bos.write(len);
  39.                         }
  40.                         bos.flush();
  41.                         pw.println("恭喜,上传成功!");
  42.                         bis.close();
  43. //                        os.close();
  44.                         bos.close();
  45.                         s.close();
  46.                 } catch (IOException e) {
  47.                        
  48.                         e.printStackTrace();
  49.                 }
  50.         }
  51. }
  52. public class ServerPic{
  53.        
  54.         public static void main(String[] args) {
  55.                 try {
  56.                         ServerSocket ss = new ServerSocket(10002);
  57.                         while(true){
  58.                                 Socket s=ss.accept();
  59.                                 new Thread(new PicThread2(s)).start();
  60.                         }
  61.                 } catch (IOException e) {
  62.                        
  63.                         e.printStackTrace();
  64.                 }
  65.         }
  66. }
复制代码


附上问题的图片:



问题图片.jpg (21.23 KB, 下载次数: 48)

问题图片.jpg

评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1 淡定

查看全部评分

11 个回复

倒序浏览
File f=new File(file,"1.jpg");

25.                int count=0;

26.                while(f.exists()){

27.                        f=new File(file,ip+"("+(count++)+")"+".jpg");

如果f不存在呢?这应该需要判断下,不然下面写入f就会失败
回复 使用道具 举报
刘家斌 发表于 2014-11-3 14:09
File f=new File(file,"1.jpg");

25.                int count=0;

f,存在的,while判断的是:循环来判断f,如果存在 ,就依次顺延+1,关键是这程序运行有点问题,你运行试试看
回复 使用道具 举报
坚持525 发表于 2014-11-3 14:14
f,存在的,while判断的是:循环来判断f,如果存在 ,就依次顺延+1,关键是这程序运行有点问题,你运行试试 ...

哦,没注意你竟然范了这种错误,你把main方法定义才Runnable子类里面,你创建线程的时候创建了能独立运行的对象,必然端口被占用啊
回复 使用道具 举报
可以尝试获取下服务端的s的端口,看看是不是端口的问题引起掉线,所以传输数据不完整。
回复 使用道具 举报
问题很多,我们一个一个来说:
clientPic第19行:获取的信息是字符,所以用BufferedReader
clientPic第22行:使用pw.write(len);用write方法可以写入一个int类型的后8位,用print你会将整个int写入流中,而且你加个ln是想干什么?字节流还加换行?
clientPic第25行:读取一行字符用 xx.readLine()方法,且前面用String类型接收。
下面是ServerPic
ServerPic第32行:FileOutput(f,ture);加上参数ture,为了续写文件,要不然你写一个覆盖一个
ServerPic第33行:服务器端反馈信息用的是字符,使用PrintWriter
最后两点建议:
1,ServerPic在上传完图片之后关闭关闭和图片关联的流资源,否则服务器不结束,图片会一直占用资源
2,在读写的时候最好使用byte[]将数据先缓存到字节数组中,提高一下效率

评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1 赞一个!

查看全部评分

回复 使用道具 举报 1 0
本帖最后由 坚持525 于 2014-11-4 15:26 编辑
刘家斌 发表于 2014-11-3 17:59
哦,没注意你竟然范了这种错误,你把main方法定义才Runnable子类里面,你创建线程的时候创建了能独立运行 ...

我复制问题时,复制错了,找到了问题,是Client的PrintStream出错了,修改后,可以运行了。还是谨记,用了Buffer,记着要flush啊,我就是忘了刷新呐
回复 使用道具 举报
OCTSJimmy 发表于 2014-11-3 18:24
可以尝试获取下服务端的s的端口,看看是不是端口的问题引起掉线,所以传输数据不完整。
...

谢谢大家指正,正确代码已改正,谢谢!
回复 使用道具 举报
WakeUp 发表于 2014-11-3 22:09
问题很多,我们一个一个来说:
clientPic第19行:获取的信息是字符,所以用BufferedReader
clientPic第22行 ...

谢谢你耐心的指正,我找到错误了,最主要是用了缓冲区就要记着flush( )的,我的client的PrintStream也用的不对,学习了
回复 使用道具 举报
本帖最后由 坚持525 于 2014-11-4 15:39 编辑
坚持525 发表于 2014-11-4 15:26
谢谢你耐心的指正,我找到错误了,最主要是用了缓冲区就要记着flush( )的,我的client的PrintStream也用 ...

http://newslxw.iteye.com/blog/1611055这是我看的关于PrintStream的技术页,但还是有点迷糊,printStream输出图片数据时,难道不能用print()?只能是readLine()和println( )一起用??你是怎么理解的呢?【注】:我把程序的Client的printStream换掉就可以了,why???
回复 使用道具 举报
坚持525 发表于 2014-11-4 15:34
http://newslxw.iteye.com/blog/1611055这是我看的关于PrintStream的技术页,但还是有点迷糊,printStream ...

你应该知道读取一个字节byte,图片数据有可能会读到连续的1111 1111这种8个1的情况,它等于-1,即程序会认为读到文件末尾了,为了避免这种情况,java在使用read方法时,将读取到的字节&255,取其后8位,前面补零,这样就避免了读到连续1的情况程序停止,而write方法则是在写入的时候是取这个int型数据的后8位即一个byte写入,print方法则是将整个int的16位都写入,所以会出错。

评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1 再奖励

查看全部评分

回复 使用道具 举报
WakeUp 发表于 2014-11-4 19:44
你应该知道读取一个字节byte,图片数据有可能会读到连续的1111 1111这种8个1的情况,它等于-1,即程序会 ...

好的,查看了一下API文档,确实是那么做的,谢谢你!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马