TCP和UDP的简单实现与运用

本文介绍了TCP和UDP的基本特性。TCP提供面向连接、可靠的字节流服务,确保数据的正确到达,而UDP则是简单、不可靠的数据报传输,速度快但不保证数据完整。通过实例展示了TCP和UDP在模拟客户端与服务器连接中的应用,包括TCP的客户端和服务器端,以及UDP的发送端和接收端,适合学生和教师学习理解网络协议。

传输控制协议(TCP):TCP(传输控制协议)定义了两台计算机之间进行可靠的传输而交换的数据和确认信息的格式,以及计算机为了确保数据的正确到达而采取的措施。协议规定了TCP软件怎样识别给定计算机上的多个目的进程如何对分组重复这类差错进行恢复。协议还规定了两台计算机如何初始化一个TCP数据流传输以及如何结束这一传输。TCP最大的特点就是提供的是面向连接、可靠的字节流服务。

用户数据报协议(UDP):UDP(用户数据报协议)是一个简单的面向数据报的传输层协议。提供的是非面向连接的、不可靠的数据流传输。UDP不提供可靠性,也不提供报文到达确认、排序以及流量控制等功能。它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。因此报文可能会丢失、重复以及乱序等。但由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

1.TCP模拟客户端与服务器的连接

  • 客户端:

    public class TcpClientDemo02 {
        public static void main(String[] args) {
    
            try {
                //1.创建一个socket连接
                Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
                //2.创建一个输出流
                OutputStream os = socket.getOutputStream();
                 
                //3.读取文件
                FileInputStream fis = new FileInputStream(new File("www.jpg")); //文件路径,默认在根目录
                //4.写出文件
    
                byte[] buffer = new byte[1024]; //建立缓冲区
                int len;
                while ((len=fis.read(buffer))!=-1){
                    os.write(buffer,0,len);
                }
    
                //通知服务器已发送完毕
                socket.shutdownOutput();
    
                //确定服务器接收完毕,才能断开服务器
                InputStream inputStream = socket.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte[] buffer2=new byte[1024];
                int len2;
                while ((len2=inputStream.read(buffer2))!=-1){
                    baos.write(buffer2,0,len2);
                }
                System.out.println(baos.toString());
    
                System.out.println("文件传输完毕!");
                //5.关闭资源
                os.close();
                fis.close();
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    
  • 服务器端

    public class TcpServerDemo02 {
        public static void main(String[] args) {
            //1.创建服务
    
            try {
                ServerSocket serverSocket = new ServerSocket(9000);
                //2.监听客户端的连接
                System.out.println("服务端正在等待连接...");
                Socket socket = serverSocket.accept();
    
                //3.获取输入流
                InputStream is = socket.getInputStream();
    
                //4.文件输出
                FileOutputStream fos = new FileOutputStream(new File("receive.jpg")); //接收的文件名字,自定义
                byte[] buffer = new byte[1024];
                int len;
                while ((len=is.read(buffer))!=-1){
                    fos.write(buffer,0,len);
                }
    
                //通知客户端已接收完毕
                OutputStream os = socket.getOutputStream();
                os.write("我已接收完毕,你可以断开了".getBytes());
    
                //5.关闭资源
                fos.close();
                is.close();
                socket.close();
                serverSocket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    

2.UDP模拟客户端与服务器的连接:一个简单的多线程模拟对话程序,双方都具有发送和接收信息的功能

  • 发送端

    public class TalkSend implements Runnable{
        DatagramSocket socket =null;
        BufferedReader reader =null;
    
        private int fromPort;
        private String toIP;
        private int toPort;
    
        public TalkSend(int fromPort, String toIP, int toPort) {
            this.fromPort = fromPort;
            this.toIP = toIP;
            this.toPort = toPort;
            try {
                socket=new DatagramSocket(fromPort);
                reader=new BufferedReader(new InputStreamReader(System.in));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
            System.out.println("请输入:");
            while (true){
                try {
                    String data = reader.readLine();
                    byte[] datas=data.getBytes(StandardCharsets.UTF_8);
                    DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort));
                    socket.send(packet);
                    //System.out.println("发送完毕!");
                    if (data.equals("bye")){
                        break;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            socket.close();
        }
    
    }
    
    
  • 接收端

    public class TalkReceive implements Runnable{
        DatagramSocket socket =null;
        private int port;
        private String msgFrom;
    
        public TalkReceive(int port,String msgFrom) {
            this.port = port;
            this.msgFrom=msgFrom;
            try {
                socket = new DatagramSocket(port);
            } catch (SocketException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
            System.out.println("服务器已启动...");
    
            while (true){
                //准备接收包裹
                byte[] container=new byte[1024]; //接收的容器
                DatagramPacket packet = new DatagramPacket(container, 0, container.length);
                try {
                    socket.receive(packet); //接收
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
                //如果bye就断开连接
                byte[] data=packet.getData(); //获取接收的数据
                String receiveData=new String(data,0, packet.getLength());
    
                System.out.println(msgFrom+":"+receiveData);
                if (receiveData.equals("bye")){
                    break;
                }
            }
            socket.close();
    
        }
    }
    
    
  • 学生

    public class TalkStudent {
        public static void main(String[] args) {
            //开启两个线程,接收与发送
            new Thread(new TalkReceive(8888,"老师")).start(); //学生接收教师消息
            new Thread(new TalkSend(7777,"localhost",9999)).start();
        }
    }
    
  • 教师

    public class TalkTeacher {
        public static void main(String[] args) {
            //开启两个线程,接收与发送
            new Thread(new TalkReceive(9999,"学生")).start(); //教师接收学生消息
            new Thread(new TalkSend(5555,"localhost",8888)).start();
        }
    }
    

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值