java入门篇14 --- tcp/udp

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
        }
    }
}

以上是关于java入门篇14 --- tcp/udp的主要内容,如果未能解决你的问题,请参考以下文章

Python 之 Socket编程(TCP/UDP)

web入门-UDP/TCP/HTTP/HTTPS

计算机网络入门基础篇——运输层

计算机网络入门基础篇——运输层

JAVA网络编程知识学习

Qt TCP/UDP 网络协议入门实操TCP通讯