57-14网络编程

74 阅读4分钟
     OutputStream getOutputStream():  获取客户端的字节输出流对象,用来给服务器端发送请求信息
     InputStream getInputStream(): 获取客户端的字节输入流对象,用读取服务器端发送回来的响应信息
    客户端 构造方法:  public Socket(String host, int port)
     参数:  String host: 客户端要连接的服务器端的ip地址 int port: 客户端要连接的服务器端的端口号
     注意:  只要创建客户端Socket对象,就会完成与服务器端的三次握手,建立与服务器端的连接  
      服务器  构造方法: ServerSocket(int port)
                参数:  int port: 端口号,必须和客户端访问的端口号保持一致
                注意:  服务器端不用指定ip地址,在哪台机器上运行,就是用该机器的ip地址  
       Socket accept(): 服务器端获取到连接服务器的客户端的Socket对象
能够编写TCP协议下字符串数据传输程序
客户端
public class Demo02Client {
    public static void main(String[] args) throws IOException { 
        Socket client = new Socket("127.0.0.1",6666);         
        OutputStream netOs = client.getOutputStream(); 
        netOs.write("老师在吗?我今天迟到了?.....".getBytes()); 
        InputStream netIs = client.getInputStream(); 
        byte[] bs = new byte[1024];
        int len = 0;
        len = netIs.read(bs);
        System.out.println("客户端收到服务器端的响应信息: "+new String(bs,0,len));
        //6.关闭资源
        netIs.close();
        netOs.close();
        client.close();
    }
}
服务端
public class Demo03Server {
    public static void main(String[] args) throws IOException {
        //1.创建服务器端ServerSocket对象,指定端口号(必须和客户端访问的端口号保持一致)
        ServerSocket server = new ServerSocket(6666);
        //2.服务器端ServerSocket对象调用accept方法,获取到连接服务器的客户端的Socket对象
        Socket client = server.accept();
        //3.客户端Socket对象调用getInputStream方法,获取服务器端的字节输入流对象
        InputStream netIs = client.getInputStream();
        //4.服务器端的字节输入流对象调用read方法,读取客户端发送过来的字节数据(请求)
        int len = 0;
        byte[] bs = new byte[1024];
        len = netIs.read(bs);
        System.out.println("服务器端接收到客户端的请求信息: "+new String(bs,0,len));
        //5.客户端Socket对象调用getOutputStream方法,获取服务器端的字节输出流对象
        OutputStream netOs = client.getOutputStream();
        //6.获取服务器端的字节输出流对象调用write方法给客户端写出字节数据(响应)
        netOs.write("迟到真不应该,按照之前的承诺,那你来选择: 1.唱歌 2.跳舞...".getBytes());
        //7.关闭资源
        netOs.close();
        netIs.close();
        client.close();
        server.close();
    }
}    
能够理解TCP协议下文件上传案例--多线程版本(手动开启线程)
问题1: 修改客户端代码    客户端没有读取到服务器端的"文件上传成功" 响应信息 
       解决方案:        shutDownOutputStream():
       销毁客户端的字节输出流,相当于给服务		器发送-1 
    问题2:修改服务器端代码    在服务器端保存文件时,随机生成不重复的文件名 
    问题3多线程    可以利用线程池进行再次优化。
/*
    定义Runnable接口的实现类
    需要使用构造方法,传递客户端Socket对象
 */
public class MyUploadFileTask implements Runnable {
    private Socket client;
    public MyUploadFileTask(Socket client) {
        this.client = client;
    }

    @Override
    public void run() {
        try {
            //3.连接服务器的客户端Socket对象调用getInputStream方法,
            //获取服务器端的字节输入流对象(读取客户端发送的请求数据的)
            InputStream netIs = client.getInputStream();
            //UUID.randomUUID().toString();//产生一个永不重复的字符串
            //产生尽可能不重复的文件名
            String fileName = System.currentTimeMillis()
                +new Random().nextInt()+ ".flv";
            //4.创建文件字节输出流FileOutputStream对象,绑定服务器端的目标文件服务器端的字节输入流对象调用read方法,读取客户端发送过来的字节数据(请求) 
            OutputStream fos = 
                new FileOutputStream(new File("day12\\upload\\to",fileName));
            //5.循环读(客户端)写(服务器端的本地文件)
            int len = 0;
            byte[] bs = new byte[1024];
            while ((len = netIs.read(bs)) != -1) {
                fos.write(bs,0,len);
            }
            //6.连接服务器的客户端Socket对象调用getOutputStream方法,
            //获取服务器端的字节输出流对象(给客户端发送的响应数据的)
            OutputStream netOs = client.getOutputStream();
            //7.服务器端的字节输出流对象调用write方法,给客户端发送的响应数据的
            netOs.write("文件上传成功!!!!!!!!".getBytes());
            //8.关闭资源: 严格来讲,应该写在finally中
            netOs.close();
            netIs.close();
            fos.close();
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 服务器改为多线程版本:使用线程池完成
public class Demo06UpLoadServer {
    public static void main(String[] args) throws IOException {
        //创建线程池对象
        ExecutorService es = Executors.newFixedThreadPool(80);
        //1.创建服务器端ServerSocket对象,指定端口号
        ServerSocket server = new ServerSocket(7777);
        //死循环
        while(true) {
            //2.服务器端ServerSocket对象调用accept方法,获取连接服务器的客户端Socket对象
            Socket client = server.accept();
            //从线程池中获取一个线程对象,执行文件上传任务
            es.submit(new MyUploadFileTask(client));
        }
    }
}
--