网络编程

1.ip地址(InetAddress类)
  • public static InetAddress getLocalHost()  获取本机IP,会以一个inetAddress的对象返回
  •  public static InetAddress getByName(String host)   根据ip地址或者域名,返回一个inetAddress对象
  •  public String getHostName()    获取该ip地址对象对应的主机名
  • public String getHostAddress() 获取该ip地址对象中的ip地址信息
  • public boolean isReachable(int timeout)    在指定毫秒内,判断主机与该ip对应的主机是否能连通
public class Demo1 {
    public static void main(String[] args) throws IOException {

        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost);

        InetAddress inetAddress = InetAddress.getByName("www.baidu.com");
        System.out.println(inetAddress);

        System.out.println(inetAddress.getHostAddress());
        System.out.println(inetAddress.getHostName());

        System.out.println(inetAddress.isReachable(1000));
    }
}
2.udp-快速入门
  • 客户端:发数据

  • 实现步骤
     1. 创建DatagramSocket对象(客户端对象)---->扔韭菜的人
     2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)---->韭菜盘子
     3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象---->开始抛出韭菜
     4. 释放资源

  • 使用的API
       ① DatagramSocket: 客户端、服务端
           ⑴ public DatagramSocket()创建客户端的Socket对象, 系统会随机分配一个端口号
           ⑵ public void send(DatagramPacket dp)    发送数据包

       ② DatagramPacket:数据包
            public DatagramPacket(byte[] buf, int length, InetAddress address, int port)  创建发出去的数据包对象

public class Client {
    public static void main(String[] args) throws IOException {
//        1. 创建DatagramSocket对象(客户端对象)---->扔韭菜的人
        DatagramSocket client = new DatagramSocket();
//        2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)---->韭菜盘子
        byte[] bytes = "一捆韭菜".getBytes(StandardCharsets.UTF_8);
        InetAddress localHost = InetAddress.getLocalHost();
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, localHost, 8888);
//        3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象---->开始抛出韭菜
        client.send(datagramPacket);
//        4. 释放资源
        client.close();

    }
}
  • 服务端:接收数据(必须用8888)

  • 实现步骤
    1.创建DatagramSocket对象并指定端口(服务端对象)  ---->接韭菜的人
    2.创建DatagramPacket对象接收数据(数据包对象)---->韭菜盘子 3. 使用3.DatagramSocket对象的receive方法,传入DatagramPacket对象 ---->开始接收韭菜
    4. 打印结果
    5. 释放资源

  • 使用的API
        DatagramSocket: 客户端、服务端
            public DatagramSocket(int port)    创建服务端的Socket对象, 并指定端口号
            public void receive(DatagramPacket p)  使用数据包接收数据

        DatagramPacket:数据包
            public DatagramPacket(byte[] buf, int length)  创建用来接收数据的数据包
            public int getLength() 获取数据包,实际接收到的字节个数

public class Server {
    public static void main(String[] args) throws IOException {
//        1. 创建DatagramSocket对象并指定端口(服务端对象)  ---->接韭菜的人
        DatagramSocket server = new DatagramSocket(8888);
//        2. 创建DatagramPacket对象接收数据(数据包对象)---->韭菜盘子
        byte[] bytes = new byte[64*1024];
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
//        3. 使用DatagramSocket对象的receive方法,传入DatagramPacket对象 ---->开始接收韭菜
        server.receive(datagramPacket);
//        获取数据包的ip和端口
        String hostAddress = datagramPacket.getAddress().getHostAddress();
        int port = datagramPacket.getPort();
//        4. 打印结果
        String str = new String(bytes,0, datagramPacket.getLength());
        System.out.println("hostAddress="+hostAddress+",port="+port+",str=="+str);
//        5. 释放资源
        server.close();
    }
}
3.udp-多发多收
  • 客户端:  发数据

  • 实现步骤:

         1. 创建DatagramSocket对象(客户端对象)---->扔韭菜的人

         2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)---->韭菜盘子
         3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象---->开始抛出韭菜
         4. 释放资源

  • 使用的API

    DatagramSocket: 客户端、服务端
        public DatagramSocket()创建客户端的Socket对象, 系统会随机分配一个端口号
        public void send(DatagramPacket dp)    发送数据包

    DatagramPacket:数据包
        public DatagramPacket(byte[] buf, int length, InetAddress address, int port)  创建发出去的数据包对象

public class Client {
    public static void main(String[] args) throws IOException {
//        1. 创建DatagramSocket对象(客户端对象)---->扔韭菜的人
        DatagramSocket client = new DatagramSocket();
//        创建键盘监视对象
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("请输入内容:");
            String msg = scanner.next();
//        用户输入exit,就退出输入
            if (msg.equals("exit")) {
//            退出
                break;
            }
//        2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)---->韭菜盘子
            byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
            InetAddress localHost = InetAddress.getLocalHost();
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, localHost, 8888);
//        3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象---->开始抛出韭菜
            client.send(datagramPacket);
        }
//        4. 释放资源
        client.close();

    }
}

  • 服务端:接收数据(必须用8888)

  • 实现步骤

      1. 创建DatagramSocket对象并指定端口(服务端对象)  ---->接韭菜的人
      2. 创建DatagramPacket对象接收数据(数据包对象)---->韭菜盘子
      3. 使用DatagramSocket对象的receive方法,传入DatagramPacket对象 ---->开始接收韭菜
     4. 打印结果
     5. 释放资源

  • 使用的API

    DatagramSocket: 客户端、服务端
        public DatagramSocket(int port)    创建服务端的Socket对象, 并指定端口号
        public void receive(DatagramPacket p)  使用数据包接收数据

    DatagramPacket:数据包
        public DatagramPacket(byte[] buf, int length)  创建用来接收数据的数据包
        public int getLength() 获取数据包,实际接收到的字节个数

4.tcp-快速入门

①客户端
    发数据

②实现步骤
    1. 创建客户端的Socket对象,请求与服务端的连接
    2. 使用socket对象调用getOutputStream()方法得到字节输出流
    3. 使用字节输出流完成数据的发送
    4. 释放资源:关闭socket管道

③使用的API
    public Socket(String host , int port) 根据指定的服务器ip、端口号请求与服务端建立连       接,连接通过,就获得了客户端socket
        public OutputStream getOutputStream()  获得字节输出流对象
        public InputStream getInputStream()    获得字节输入流对象

public class Client {
    public static void main(String[] args) throws IOException {
//        1. 创建客户端的Socket对象,请求与服务端的连接
        Socket socket = new Socket("127.0.0.1",8888);
        //        2. 使用socket对象调用getOutputStream()方法得到字节输出流
        OutputStream outputStream = socket.getOutputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
//        获取用户输入的键盘内容
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("请输入内容:");
            String str = scanner.nextLine();
            if(str.equals("exit")){
                break;
            }
//        3. 使用字节输出流完成数据的发送
            dataOutputStream.writeUTF(str);
        }
//        4. 释放资源:关闭socket管道
        dataOutputStream.close();
        outputStream.close();
        socket.close();
    }
}

①服务端 :接收数据

②实现步骤

    1. 创建ServerSocket对象,注册服务端端口

    2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象

    3. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收

    4. 释放资源:关闭socket管道

③使用的API

public ServerSocket(int port) 为服务端程序注册端口

public Socket accept() 阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象 

public class Server {
    public static void main(String[] args) throws IOException {
//        1. 创建ServerSocket对象,注册服务端端口
        ServerSocket serverSocket = new ServerSocket(8888);
//        2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
        Socket socket = serverSocket.accept();
//        3. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收
        InputStream inputStream = socket.getInputStream();
        DataInputStream dataInputStream = new DataInputStream(inputStream);
        while(true) {
            try {
//        获取客户端发送的数据
                String str = dataInputStream.readUTF();
                String hostAddress = socket.getInetAddress().getHostAddress();
                int port = socket.getPort();
                System.out.println("客户端ip:" + hostAddress + "客户端的port:" + port + ",内容:" + str);
            }catch (Exception e){
                System.out.println("有客户端断开");
                break;
            }
        }
//        4. 释放资源:关闭socket管道
//        dataInputStream.close();
//        inputStream.close();
//        socket.close();
//        serverSocket.close();
    }
}
5. tcp-多客户端通信

①客户端
    发数据

②实现步骤
    1. 创建客户端的Socket对象,请求与服务端的连接
    2. 使用socket对象调用getOutputStream()方法得到字节输出流
    3. 使用字节输出流完成数据的发送
    4. 释放资源:关闭socket管道

③使用的API
    public Socket(String host , int port) 根据指定的服务器ip、端口号请求与服务端建立连接,连接通过,就获得了客户端socket
        public OutputStream getOutputStream()  获得字节输出流对象
        public InputStream getInputStream()    获得字节输入流对象

public class Client {
    public static void main(String[] args) throws IOException {
//        1. 创建客户端的Socket对象,请求与服务端的连接
        Socket socket = new Socket("127.0.0.1",8888);
        //        2. 使用socket对象调用getOutputStream()方法得到字节输出流
        OutputStream outputStream = socket.getOutputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
//        获取用户输入的键盘内容
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("请输入内容:");
            String str = scanner.nextLine();
            if(str.equals("exit")){
                break;
            }
//        3. 使用字节输出流完成数据的发送
            dataOutputStream.writeUTF(str);
            dataOutputStream.flush();
        }
//        4. 释放资源:关闭socket管道
        dataOutputStream.close();
        outputStream.close();
        socket.close();
    }
}

①服务端
    接收数据

②实现步骤
    1. 创建ServerSocket对象,注册服务端端口
    2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
    3. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收
    4. 释放资源:关闭socket管道

③使用的API
    public ServerSocket(int port)  为服务端程序注册端口
        public Socket accept() 阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象

public class Server {
    public static void main(String[] args) throws IOException {

//        创建线程池
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                5,
                10,
                30,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
//        1. 创建ServerSocket对象,注册服务端端口
        ServerSocket serverSocket = new ServerSocket(8888);
//        2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
        while (true) {
            Socket socket = serverSocket.accept();
//            创建任务对象
            SocketTask socketTask = new SocketTask(socket);
//            把任务交给子线程
//            new Thread(socketTask,"线程---").start();
            poolExecutor.execute(socketTask);
        }
    }
}

class SocketTask implements Runnable{

    private Socket socket;
    public SocketTask(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            //        3. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收
            InputStream inputStream = socket.getInputStream();
            DataInputStream dataInputStream = new DataInputStream(inputStream);
            while (true) {
//        获取客户端发送的数据
                try {
                    String str = dataInputStream.readUTF();
                    String hostAddress = socket.getInetAddress().getHostAddress();
                    int port = socket.getPort();
                    System.out.println(Thread.currentThread().getName() + ",客户端ip:" + hostAddress + "客户端的port:" + port + ",内容:" + str);
                }catch (Exception e){
                    System.out.println("客户单已经断开");
                    break;
                }
            }
        }catch (Exception e){
//            e.printStackTrace();
            System.out.println("获取输入内容失败");
        }

    }
}
6.bs架构
/**
 * 服务端
 */
public class MainServer {
    public static void main(String[] args) throws IOException {

//        创建处理连接的线程池
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                5,
                10,
                30,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
//        创建服务端对象
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true) {
//        循环接收客户端浏览器的连接请求
            Socket socket = serverSocket.accept();
//            创建任务类
            SocketRunable socketRunable = new SocketRunable(socket);
//            把socket交给子线程
            poolExecutor.execute(socketRunable);
        }
    }
}

/**
 * 处理浏览器连接的 任务类
 */
public class SocketRunable implements Runnable{
    private Socket socket;
    public SocketRunable(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        System.out.println("接收到浏览器的请求");
        try {
            String hostAddress = socket.getInetAddress().getHostAddress();
            int port = socket.getPort();
            System.out.println(hostAddress+":"+port);
            OutputStream outputStream = socket.getOutputStream();
            PrintStream printWriter = new PrintStream(outputStream);
            printWriter.println("HTTP/1.1   200   OK");
            printWriter.println("Content-Type : text/html;charset=UTF-8");
            printWriter.println();
            printWriter.println("<div style=\"color: black;font-size: 120px;text-align: center\">");
            printWriter.println("黑马程序员666");
            printWriter.println("</div>");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值