黑马程序员技术交流社区

标题: 关于ServerSocket.accept()方法 [打印本页]

作者: 吴玉辉    时间: 2012-4-15 20:59
标题: 关于ServerSocket.accept()方法
  1. import java.io.*;
  2. import java.net.*;
  3. class  PicClient
  4. {
  5.         public static void main(String[] args)throws Exception
  6.         {
  7.                 if(args.length!=1)
  8.                 {
  9.                         System.out.println("请选择一个jpg格式的图片");
  10.                         return ;
  11.                 }




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

  17.                 }

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

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



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

  30.                 FileInputStream fis = new FileInputStream(file);

  31.                 OutputStream out = s.getOutputStream();

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

  33.                 int len = 0;

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

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

  40.                 InputStream in = s.getInputStream();

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

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

  44.                 fis.close();
  45.                 s.close();
  46.         }
  47. }

  48. /*
  49. 服务端

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

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



  56. 如何定义线程呢?

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

  59. class PicThread implements Runnable
  60. {

  61.         private Socket s;
  62.         PicThread(Socket s)
  63.         {
  64.                 this.s = s;
  65.         }
  66.         public void run()
  67.         {

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

  73.                         InputStream in = s.getInputStream();

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

  75.                         File file = new File(dir,ip+"("+(count)+")"+".jpg");//防止重名被覆盖

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

  78.                         FileOutputStream fos = new FileOutputStream(file);

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

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

  85.                         OutputStream out = s.getOutputStream();

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

  87.                         fos.close();

  88.                         s.close();
  89.                 }
  90.                 catch (Exception e)
  91.                 {
  92.                         throw new RuntimeException(ip+"上传失败");
  93.                 }
  94.         }
  95. }
  96. class  PicServer
  97. {
  98.         public static void main(String[] args) throws Exception
  99.         {
  100.                 ServerSocket ss = new ServerSocket(10007);

  101.                 while(true)
  102.                 {
  103.                         [color=Red]Socket s = ss.accept();[/color]
  104.                         new Thread(new PicThread(s)).start();

  105.                
  106.                 }

  107.                 //ss.close();
  108.         }
  109. }
复制代码
为什么Socket s = ss.accept();不能拿到循环外面?难道它有类似同步锁的功能?
作者: 张卯    时间: 2012-4-15 21:07
拿到循环外面服务器玩一次就不干了~
作者: 刘基军    时间: 2012-4-15 22:05
放循环里面可以不停地监听端口,一旦有连接过来时,就可以为这个连接创建线程,为其服务.
要是拿出来,那就只能对一个客户端进行服务.
作者: liuyang    时间: 2012-4-15 23:19
没有同步锁的功能,放在循环是为了不停地执行,以便不停的监听,放在循环外执行一次就完了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2