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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 陈洋 中级黑马   /  2013-9-25 00:17  /  1400 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 陈洋 于 2013-9-25 11:19 编辑

Socket s = ss.accept();
我想知道这里为什么不放到run方法中,
而下面的开启线程传入的Runnable实现类就不需要
传入Socket对象了,通过线程启动后,在创建Socket对象。
  1. /*
  2. 需求:上传图片。



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

  11. */

  12. import java.io.*;
  13. import java.net.*;
  14. class  PicClient
  15. {
  16.         public static void main(String[] args)throws Exception
  17.         {
  18.                 if(args.length!=1)//为什么这里判断长度是1,就防止乱传参数呢?
  19.                 {
  20.                         System.out.println("请选择一个jpg格式的图片");
  21.                         return ;
  22.                 }




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

  28.                 }

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

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



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

  41.                 FileInputStream fis = new FileInputStream(file);

  42.                 OutputStream out = s.getOutputStream();

  43.                 byte[] buf = new byte[1024];

  44.                 int len = 0;

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

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

  51.                 InputStream in = s.getInputStream();

  52.                 byte[] bufIn = new byte[1024];

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

  55.                 fis.close();
  56.                 s.close();
  57.         }
  58. }

  59. /*
  60. 服务端

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

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



  67. 如何定义线程呢?

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

  70. class PicThread implements Runnable
  71. {

  72.         private Socket s;
  73.         PicThread(Socket s)
  74.         {
  75.                 this.s = s;
  76.         }
  77.         public void run()
  78.         {

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

  84.                         InputStream in = s.getInputStream();

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

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

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

  89.                         FileOutputStream fos = new FileOutputStream(file);

  90.                         byte[] buf = new byte[1024];

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

  96.                         OutputStream out = s.getOutputStream();

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

  98.                         fos.close();

  99.                         s.close();
  100.                 }
  101.                 catch (Exception e)
  102.                 {
  103.                         throw new RuntimeException(ip+"上传失败");
  104.                 }
  105.         }
  106. }



  107. class  PicServer
  108. {
  109.         public static void main(String[] args) throws Exception
  110.         {
  111.                 ServerSocket ss = new ServerSocket(10007);

  112.                 while(true)
  113.                 {
  114.                         Socket s = ss.accept();//我想知道这里为什么不放到run方法中,
  115.                                                                         //而下面的开启线程传入的Runnable实现类就不需要
  116.                                                                         //传入Socket对象了,通过线程启动后,在创建Socket对象。

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

  118.                
  119.                 }

  120.                 //ss.close();
  121.         }
  122. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
黄兴旺 + 1

查看全部评分

2 个回复

倒序浏览
Socket s = ss.accept(); 如果这个放到new Thread()内,那么就不是一个服务器了。有几个线程就是几个服务器。 服务器只有一个,客户端发来请求上传数据,这时候将上传数据的代码到线程里分别去运行,
new Thread(new PicThread(s)).start(); 实现客户端并发上传的效果。
回复 使用道具 举报
非常好的资源,谢谢分享!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马