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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 兜兜转转 中级黑马   /  2013-8-15 09:10  /  1731 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 兜兜转转 于 2013-8-15 09:23 编辑

/*
需求:上传图片。



*/
/*
客户端。
1,服务端点。
2,读取客户端已有的图片数据。
3,通过socket 输出流将数据发给服务端。
4,读取服务端反馈信息。
5,关闭。

*/

import java.io.*;
import java.net.*;
class  PicClient
{
        public static void main(String[] args)throws Exception
        {
                if(args.length!=1)
                {
                        System.out.println("请选择一个jpg格式的图片");
                        return ;
                }




                File file = new File(args[0]);
                if(!(file.exists() && file.isFile()))
                {
                        System.out.println("该文件有问题,要么补存在,要么不是文件");
                        return ;

                }

                if(!file.getName().endsWith(".jpg"))
                {
                        System.out.println("图片格式错误,请重新选择");
                        return ;
                }

                if(file.length()>1024*1024*5)
                {
                        System.out.println("文件过大,没安好心");
                        return ;
                }
               



                Socket s = new Socket("192.168.1.254",10007);

                FileInputStream fis = new FileInputStream(file);

                OutputStream out = s.getOutputStream();

                byte[] buf = new byte[1024];

                int len = 0;

                while((len=fis.read(buf))!=-1)
                {
                        out.write(buf,0,len);
                }

                //告诉服务端数据已写完
                s.shutdownOutput();

                InputStream in = s.getInputStream();

                byte[] bufIn = new byte[1024];

                int num = in.read(bufIn);
                System.out.println(new String(bufIn,0,num));

                fis.close();
                s.close();
        }
}

/*
服务端

这个服务端有个局限性。当A客户端连接上以后。被服务端获取到。服务端执行具体流程。
这时B客户端连接,只有等待。
因为服务端还没有处理完A客户端的请求,还有循环回来执行下次accept方法。所以
暂时获取不到B客户端对象。

那么为了可以让多个客户端同时并发访问服务端。
那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。



如何定义线程呢?

只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入run方法中。
*/

class PicThread implements Runnable
{

        private Socket s;
        PicThread(Socket s)
        {
                this.s = s;
        }
        public void run()
        {

                int count = 1;
                String ip  = s.getInetAddress().getHostAddress();
                try
                {
                        System.out.println(ip+"....connected");

                        InputStream in = s.getInputStream();

                        File dir =  new File("d:\\pic");

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

                        while(file.exists())
                                file = new File(dir,ip+"("+(count++)+")"+".jpg");

                        FileOutputStream fos = new FileOutputStream(file);

                        byte[] buf = new byte[1024];

                        int len = 0;
                        while((len=in.read(buf))!=-1)
                        {
                                fos.write(buf,0,len);
                        }

                        OutputStream out = s.getOutputStream();

                        out.write("上传成功".getBytes());

                        fos.close();

                        s.close();
                }
                catch (Exception e)
                {
                        throw new RuntimeException(ip+"上传失败");
                }
        }
}



class  PicServer
{
        public static void main(String[] args) throws Exception
        {
                ServerSocket ss = new ServerSocket(10007);

                while(true)
                {
                        Socket s = ss.accept();

                        new Thread(new PicThread(s)).start();

               
                }

                //ss.close();
        }
}


代码内的红色不分是我要请教的问题,声明,以上是毕老师的源代码。。。。。。。
int count = 1;//当初老师说为了防止每个客户端一进来开启线程都共享一个count变量,所以不能定义为成员变量,就定义在run方法里面
new Thread(new PicThread(s)).start();//可是这里不是没一个客户端访问服务器进来之后,都会执行这里,new PicThread(s)都会new出一个匿名对像吗?难道他们是同一个象?如果不是同一个对象,那么count就不存在共享一个count的问题才对,求解。



评分

参与人数 1技术分 +1 收起 理由
张智文 + 1

查看全部评分

6 个回复

正序浏览
binghaiwang 发表于 2013-8-15 13:52
我怀疑你是不是听错了,我肯定这个count变量你定义在成员还是run里边都一样, 一new新对象就会重置的 需要自 ...

哥们,还真没听错,你去拿着毕老师day24 讲那个多线程上传文件的那个例子的视频,再看一遍,我贴出来的代码就是老师的源代码
回复 使用道具 举报
我怀疑你是不是听错了,我肯定这个count变量你定义在成员还是run里边都一样, 一new新对象就会重置的 需要自己在run 方法里边定义判断来进行自增。
回复 使用道具 举报
可是我刚刚自己定义成成员变量试了一下,没有共享呢?还是我代码有问题?
回复 使用道具 举报
我个人理解哈:
new Thread(new PicThread(s)).start();//每一个客户端访问服务器进来之后,都会执行这里,new PicThread(s)都会new出一个匿名对像
不同的客户端是不同对象,不同对象都会重新调用run方法,但是不同对象的PicThread 是同一个,如果把count定义到PicThread 里,那么就是共享。
回复 使用道具 举报
本事是标记红色的,可是把代码贴到那个代码编辑器里面,就什么都看不到了,重新编辑了几次都不行,我还是直接贴村文本好了
回复 使用道具 举报
哪有红色?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马