14网络编程

55 阅读4分钟
 
/*
   构造方法:
            public Socket(String hostip地址, int port端口号)
                注意:   只要创建客户端Socket对象,就会完成与服务器端的三次握手,建立与服务器端的连接
     //1.创建客户端Socket对象,指定要连接的服务器的ip地址和端口号
        Socket client = new Socket("127.0.0.1",6666);
         //2.客户端Socket对象调用getOutputStream方法,获取客户端的字节输出流对象
        常用方法:  OutputStream netOs = client.getOutputStream();
       getOutputStream(): 获取客户端的字节输出流对象,用来给服务器端发送请求信息
       //3.客户端的字节输出流对象调用write方法给服务器写出字节数据(请求)
       netOs.write("你好服务器!!!".getBytes());
       getInputStream(): 获取客户端的字节输入流对象,用读取服务器端发送回来的响应信息
                //4.客户端Socket对象调用getInputStream方法,获取客户端的输入流对象
        InputStream netIs = client.getInputStream();
         //5.客户端的字节输入流对象调用read方法,读取服务器端发送回来的字节数据(响应)
        //假设服务器响应的数据不多,只需要使用1024长度的字节数组读取一次即可
        int len;
        byte[] bs = new byte[1024];
        len = netIs.read(bs);
        System.out.println("客户端收到服务器的响应消息: "+new String(bs,0,len));
       ServerSocket(int port端口号,必须和客户端访问的端口号保持一致)
            注意:   服务器端不用指定ip地址,在哪台机器上运行,就是用该机器的ip地址
          //1.创建服务器端ServerSocket对象,指定端口号(必须和客户端访问的端口号保持一致)
        ServerSocket server = new ServerSocket(6666);
        java.net.ServerSocket类: TCP通信的服务器端
        常用方法:
            public Socket accept(): 服务器端获取到连接服务器的客户端的Socket对象
                返回值类型:
                    java.net.Socket类: TCP通信的客户端
            //2.服务器端ServerSocket对象调用accept方法,获取到连接服务器的客户端的Socket对象
        Socket client = server.accept();
                    常用方法:

          //3.客户端Socket对象调用getInputStream方法,获取服务器端的字节输入流对象
        InputStream netIs = client.getInputStream();
                        public InputStream getInputStream():
                           获取服务器端的字节输入流对象,用读取客户端发送过来的请求信息
            public OutputStream getOutputStream():
                           获取服务器端的字节输出流对象,用来给客户端发送响应信息
           //5.客户端Socket对象调用getOutputStream方法,获取服务器端的字节输出流对象
        OutputStream netOs = client.getOutputStream();
        Thread.sleep(8000);
        导致服务器端的read方法的结果是-1
        客户端数据发送完毕后,调用方法:  shutDownOutputStream():
        销毁客户端的字节输出流,相当于给服务    器发送-1
        int len;
        byte[] bs = new byte[1024];
        while ((len = fis.read(bs)) != -1) {
            netOs.write(bs,0,len);
        }
         client.shutdownOutput();
        //5.客户端Socket对象调用getInputStream方法,获取客户端字节输入流对象(读取服
   //4.创建文件字节输出流FileOutputStream对象,绑定服务器端的目标文件
        FileOutputStream fos = new FileOutputStream("day14\upload\to\jzc.flv");
 //产生尽可能不重复的文件名
            String fileName = System.currentTimeMillis() + "" + Math.abs(new Random().nextInt()) + ".flv";

            //创建目标文件对应的File对象
            File file = new File("day14\upload\to",fileName);
//多客户端上传(单线程版本)
            //为当前新连接进来的客户端开启一条新的线程执行文件上传任务
            new Thread(new Runnable() {
                @Override
                public void run() { }
            }).start();

        }
 */

/*

问题: 服务器端: 只支持上传一次 修改为: 多客户端上传(单线程版本)
    解决方案: 服务器端改为多线程版本,来一个客户端开启一个线程
最后:  使用线程池优化

*/ public class Demo06UpLoadServerThreadPool { public static void main(String[] args) throws IOException { //String str = UUID.randomUUID().toString().replace("-",""); //使用工具类Executors调用静态方法newFixedThreadPool创建有3个线程的线程池对象 ExecutorService pool = Executors.newFixedThreadPool(3); //1.创建服务器端ServerSocket对象,指定端口号 ServerSocket server = new ServerSocket(7777); //死循环,模拟服务器一直在运行 while (true) { //2.服务器端ServerSocket对象调用accept方法,获取连接服务器的客户端Socket对象 Socket client = server.accept(); //使用线程池对象调用submit方法,提交当前客户端的文件上传任务 pool.submit(new UpLoadTask(client)); }

}

} ///* // 定义Runnable接口的实现类 // 需要使用构造方法,传递客户端Socket对象 // */ //public class UpLoadTask implements Runnable { // //进行文件上传的当前客户端Socket对象 // private Socket client; // // public UpLoadTask(Socket client) { // this.client = client; // } //} //