• java入门篇14 --- tcp/udp


    我们应该比较了解TCP/UDP,想什么应表会传网数物的计算器的七层协议,还有TCP的三次握手,四次回收,UDP的广播流,不保证收到,跳过这些基础,我们直接来看java如何实现的

    先来看一下tcp,记得想要发送的时候flush一下,这样就会把输出流写入到网络中:

    首先编写Server端

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.charset.StandardCharsets;
    
    class SocketHandler extends Thread {
        private Socket socket = null;
    
        // 将连接出手啊
        public SocketHandler(Socket s) {
            this.socket = s;
        }
    
        @Override
        public void run() {
            // 获取这个连接输入流
            try (InputStream input = this.socket.getInputStream()) {
                // 获取这个连接的输出流
                try (OutputStream output = this.socket.getOutputStream()) {
                    // 调用方法进行处理
                    hand(input, output);
                }
            } catch (IOException e) {
                try {
                    // 如果断开连接或者io错误,尝试关闭连接
                    this.socket.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
            }
            System.out.println("客户端结束连接");
        }
    
        private void hand(InputStream input, OutputStream ouput) throws IOException {
            // 将输入输出放在内存,这个也可以存入文件
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(ouput, StandardCharsets.UTF_8));
            BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
            // 先打声招呼
            writer.write("欢迎光临");
            writer.newLine();
            // 强制发送消息
            writer.flush();
            while (true) {
                // 接受一行消息
                String s = reader.readLine();
                System.out.println(s);
                // 如果输入的是 exit 就退出
                if (s.equals("exit")) {
                    writer.write("再见");
                    writer.newLine();
                    writer.flush();
                    break;
                }
                // 否则就让他继续发
                writer.write("请继续");
                writer.newLine();
                writer.flush();
            }
        }
    }
    
    public class Server {
        public static void main(String[] args) throws IOException {
            ServerSocket server = new ServerSocket(8090);  // 指定监听端口
            // 起一个循环,来不停的接受请求
            while (true) {
                Socket s = server.accept();  // 接收连接
                System.out.println(s.getRemoteSocketAddress());  // 获取客户端地址
                // 起一个线程来处理这次连接
                Thread t = new SocketHandler(s);
                t.start();
    
            }
        }
    }

    server就是起了一个无限循环,来接受客户端的连接

    接下来看一下客户端实现:

    import java.io.*;
    import java.net.Socket;
    import java.nio.charset.StandardCharsets;
    import java.util.Scanner;
    
    public class Client {
        public static void main(String[] args) throws IOException {
            Socket sock = new Socket("127.0.0.1", 8090); // 连接客户端
            // 获取输入输出流并进一步处理
            try (InputStream input = sock.getInputStream()) {
                try (OutputStream output = sock.getOutputStream()) {
                    hand(input, output);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            sock.close();
            System.out.println("客户端退出");
        }
    
        private static void hand(InputStream input, OutputStream ouput) throws IOException {
            // 将输入输出放在内存,
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(ouput, StandardCharsets.UTF_8));
            BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
            // 从终端读取消息
            Scanner s = new Scanner(System.in);
            System.out.println("接收到>>" + reader.readLine());
            while (true) {
                // 接受一行消息
                System.out.println("请输入:>>");
                // 如果输入的是 exit 就退出
                String st = s.nextLine();
                writer.write(st);
                writer.newLine();
                writer.flush();
                String recv = reader.readLine();
                System.out.println("接收到>>" + recv);
                // 否则就让他继续发
                if (recv.equals("再见")) {
                    break;
                }
            }
        }
    }

    UDP更简单一些,他不知道客户端从哪里来,有消息我就接受,并返回

    Server端:

    import java.io.*;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.nio.charset.StandardCharsets;
    
    public class Server {
        public static void main(String[] args) throws IOException, InterruptedException {
            DatagramSocket server = new DatagramSocket(8090);  // 指定监听端口
            // 起一个循环,来不停的接受请求
            while (true) {
                byte[] b = new byte[1024];
                DatagramPacket p = new DatagramPacket(b, b.length);
                server.receive(p);  // 接收连接
                String s = new String(p.getData(), p.getOffset(), p.getLength(), StandardCharsets.UTF_8);
                System.out.println(s);
                // Thread.sleep(2000);
                byte[] m = "recv".getBytes();
                // 接受数据直接返回
                p.setData(m);
                server.send(p);
            }
        }
    }

    Client端

    import java.io.*;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.nio.charset.StandardCharsets;
    import java.util.Scanner;
    
    public class Client1 {
        public static void main(String[] args) throws IOException {
            DatagramSocket sock = new DatagramSocket(); // 起一个实例化
            sock.setSoTimeout(1000);  // 设置超时时间
            sock.connect(InetAddress.getByName("127.0.0.1"), 8090);  // 去连接
            Scanner s = new Scanner(System.in);
            // 循环发送
            while (true) {
                System.out.println(">>>");
                String ss = s.nextLine();
                byte[] b = ss.getBytes();
                // 消息需要打包
                DatagramPacket p = new DatagramPacket(b, b.length);
                sock.send(p);
                byte[] recv = new byte[1024];
                DatagramPacket p1 = new DatagramPacket(recv, recv.length);
                sock.receive(p1);
                String s1 = new String(p1.getData(), p1.getOffset(), p1.getLength(), StandardCharsets.UTF_8);
                System.out.println(s1);
            }
        }
    }
  • 相关阅读:
    基础字段及选项2(11)
    模型层及ORM介绍(9)
    Luogu [P3367] 模板 并查集
    Luogu [P1958] 上学路线_NOI导刊2009普及(6)
    Luogu [P3951] 小凯的疑惑
    Luogu [P2708] 硬币翻转
    Luogu [P1334] 瑞瑞的木板(手写堆)
    一步步学习如何建立自己的个性博客~~
    Android初学者—listView用法
    SQLite命令—对表插入和修改等操作
  • 原文地址:https://www.cnblogs.com/yangshixiong/p/12178232.html
Copyright © 2020-2023  润新知