TCP知识点

一、能实现两台计算机的通信;

二、jdk中提供了二个类:一个是ServerSocket类,用于表示服务器端,一个是Socket类,用于表示客户端

三、客户端Socket的常用方法

方法声明

功能描述

int getPort()

该方法返回一个int类型对象,该对象是Socket对象与服务器端连接的端口号

InetAddress getLocalAddress()

该方法用于获取Socket对象绑定的本地IP地址,并将IP地址封装成InetAddress类型的对象返回

void close()

该方法用于关闭Socket连接,结束本次通信。在关闭socket之前,应将与socket相关的所有的输入/输出流全部关闭,这是因为一个良好的程序应该在执行完毕时释放所有的资源

InputStream getInputStream()

该方法返回一个InputStream类型的输入流对象,如果该对象是由服务器端的Socket返回,就用于读取客户端发送的数据,反之,用于读取服务器端发送的数据

OutputStream getOutputStream()

该方法返回一个OutputStream类型的输出流对象,如果该对象是由服务器端的Socket返回,就用于向客户端发送数据,反之,用于向服务器端发送数据

四、案列(传输一张图片)单线程写法 弊端只能传输一张照片 假如二个人同时给服务器传东西 其中一个人会处于等待状态

public class TCPClice {

    public static void main(String[] args) throws IOException {
        // 创建客户端对象,明确要连接的服务器所在的ip地址和端口号
        Socket sc = new Socket("127.0.0.1", 8888); //自己主机的ip地址是127.0.0.1  
        //创建文件字节输入流,明确数据源
        FileInputStream fis=new FileInputStream("D:\\io1227\\qd.png");
        // 明确目的地
        OutputStream out = sc.getOutputStream();
        byte[] by=new byte[1024];
        int len=0;
        while((len=fis.read(by))!=-1){
            out.write(by,0,len);
        }
        //告知服务器没有了 别读了
        sc.shutdownOutput();
        //接受服务器回复
        //获取字节输入流
        InputStream in=sc.getInputStream();
        //获取ip地址
        String ip=sc.getInetAddress().getHostAddress();
        len=in.read(by);
        System.out.println("ip地址为"+ip+"发送的内容为"+new String(by,0,len));
        //释放
        sc.close();
        fis.close();
    }
}
public class TCPServier {

    public static void main(String[] args) throws IOException {
        // 创建服务器端对象
        ServerSocket ser=new ServerSocket(8888);
        //创建连接并获取与我连接的客户端对象
        Socket sc=ser.accept();
        //明数据源确
        InputStream in=sc.getInputStream();
        //明确目的地 并判断是否存在
        File file =new File("D:\\upload");
        if(!file.exists()){
            file.mkdir();
        }
        //封装文件名
        String filname="oracle"+System.currentTimeMillis()+new Random().nextInt(999999)+".png";
        //明确目的地
        FileOutputStream fos=new FileOutputStream(file+file.separator+filname);//用file.separator替代了
        byte[] by=new byte[1024];
        int len=0;
        while((len=in.read(by))!=-1){
            fos.write(by,0,len);
        }
        //回复客户端
        //获取字节输出流
        OutputStream out=sc.getOutputStream();
        out.write("收到".getBytes());
        //释放资源
        sc.close();
        fos.close();
    }
}

为了解决这一弊端 使用线程池来解决:

public class Upload implements Runnable {
    private Socket sc;

    public Upload(Socket sc) {
        this.sc = sc;
    }

    public void run() {
        FileOutputStream fos = null;
        // 明数据源确
        try {
            InputStream in = sc.getInputStream();
            // 明确目的地 并判断是否存在
            File file = new File("D:\\upload");
            if (!file.exists()) {    //判断这个 D:这个文件是否存在
                file.mkdir();    //不存在的话新建这个文件夹;
            }
            // 封装文件名
            String filname = "oracle" + System.currentTimeMillis() + new Random().nextInt(999999) + ".png"; //这个地方png前面必须加. 不加.的话图片打不开
            // 明确目的地
            fos = new FileOutputStream(file + file.separator + filname);//  \\用file.separator替代了
            byte[] by = new byte[1024];
            int len = 0;
            while ((len = in.read(by)) != -1) {
                fos.write(by, 0, len);
            }
            // 回复客户端
            // 获取字节输出流
            OutputStream out = sc.getOutputStream();
            out.write("收到".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Demo01 {

    public static void main(String[] args) throws IOException {
        // 创建服务器端对象
        ServerSocket ser = new ServerSocket(8888);
        while (true) {
            // 创建连接并获取与我连接的客户端对象
            Socket sc = ser.accept();
            // 创建线程任务
            Upload up=new Upload(sc);
            //创建线程对象
            Thread th=new Thread(up);
            //开启线程
            th.start();
        }
    }
}

这样就很好解决了一个服务器可以同时传送多张照片了;

posted @ 2020-04-27 16:57  丿狂奔的蜗牛  阅读(160)  评论(0编辑  收藏  举报