UDP和TCP通信程序练习

目录

练习一:简单的信息发送

练习二:信息发送与接收

练习三:数据来自键盘输入,接收到的数据输出到控制台

练习四:简单的发送和接收数据

练习五:上传文件

练习六:上传文件,并得到服务器的反馈

练习七:服务器可以接收多个客户端上传的文件,线程封装


练习一:简单的信息发送

  • 发送端:数据来自键盘录入,直到输入的数据是bye,发送数据结束

  • 接收端:因为接收端不知道发送端什么时候停止发送,故采用死循环接收

发送端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Scanner;

public class UDP_Client2 {
    /**
     * 练习一:简单的信息发送
     *
     * 发送端:数据来自键盘录入,直到输入的数据是bye,发送数据结束
     * 接收端:因为接收端不知道发送端什么时候停止发送,故采用死循环接收
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        //发送对象
        DatagramSocket ds = new DatagramSocket();
        Scanner scanner = new Scanner(System.in);
        while(true){//字节数组
            System.out.println("请输入要发送的内容:");
            String msg = scanner.next();
            byte[] data = msg.getBytes();
            //目的地址
            InetSocketAddress address = new InetSocketAddress("localhost", 1122);
            //发送包裹
            DatagramPacket dp = new DatagramPacket(data, data.length, address);
            //发送
            ds.send(dp);
            System.out.println("已发送");
            if(msg.equals("bye")){
                System.out.println("over");
                break;
            }
        }
        //关闭
        ds.close();
    }
}

接收端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDP_Server2 {
    public static void main(String[] args) throws IOException {
        //监听指定端口
        DatagramSocket ds = new DatagramSocket(1122);
        while(true){
            System.out.println("等待接收");
            //字节数组
            byte[] data = new byte[1024];
            //接受包裹
            DatagramPacket dp = new DatagramPacket(data,data.length);
            //阻塞式接收
            ds.receive(dp);
            String res = new String(data,0,dp.getLength());
            System.out.println(res);
            if(res.equals("bye")){
                System.out.println("over");
                break;
            }
        }
        ds.close();
    }
}

运行结果:

练习二:信息发送与接收

  • 发送端:数据来自键盘录入,直到输入的数据是bye,发送数据结束,可以接收到服务端的响应

  • 接收端:接收客户端的数据信息,并且及时做出响应

发送端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Scanner;

public class UDP_Client3 {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();
        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println("请输入要发送的内容");
            String msg = sc.next();
            byte[] data = msg.getBytes();
            InetSocketAddress address = new InetSocketAddress("localhost",1223);
            DatagramPacket dp = new DatagramPacket(data,data.length,address);
            ds.send(dp);

            //接收
            System.out.println("等待接收");
            byte[] tmp = new byte[1024];
            dp = new DatagramPacket(tmp,tmp.length);
            ds.receive(dp);
            String res = new String(tmp,0,dp.getLength());
            System.out.println(res);
            if(msg.equals("bye")){
                System.out.println("over");
                break;
            }
        }
        ds.close();
    }
}

接收端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Scanner;

public class UDP_Server3 {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket(1223);
        Scanner sc = new Scanner(System.in);
        while(true){
            //接收
            System.out.println("等待接收");
            byte[] data = new byte[1024];
            DatagramPacket dp = new DatagramPacket(data,data.length);
            ds.receive(dp);
            String res = new String(data,0,dp.getLength());
            System.out.println(res);
            //发送
            System.out.println("请输入要发送的内容");
            String msg = sc.next();
            byte[] tmp = msg.getBytes();
            dp = new DatagramPacket(tmp,tmp.length,dp.getAddress(),dp.getPort());
            ds.send(dp);
            if(res.equals("bye")){
                System.out.println("over");
                break;
            }
        }
        ds.close();
    }
}

运行结果:

练习三:数据来自键盘输入,接收到的数据输出到控制台

  • 客户端: 数据来自于键盘录入,直到输入的数据是bye, 发送数据结束

  • 服务器端:接收到的数据在控制台输出

客户端:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class TCP_Client2 {
    public static void main(String[] args) throws IOException {
        //建立连接
        Scanner scanner = new Scanner(System.in);
        Socket socket = new Socket("localhost",1122);
        PrintWriter pw;
        //输入要发送的内容
        while(true){
            System.out.println("请输入要发送的内容:");
            String msg = scanner.next();
            pw = new PrintWriter(socket.getOutputStream());
            pw.println(msg);
            pw.flush();
            if(msg.equals("bye")){
                System.out.println("over");
                break;
            }
        }
        pw.close();
        socket.close();
    }
}

服务器端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class TCP_Server2 {
    public static void main(String[] args) throws IOException {
        //监听指定端口
        ServerSocket serverSocket = new ServerSocket(1122);
        //阻塞式接收
        Socket socket = serverSocket.accept();
        //将字节输入流转为带缓冲区的字符流
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String msg;
        while((msg=br.readLine())!=null){
            System.out.println(msg);
            if(msg.equals("bye")){
                System.out.println("over");
                break;
            }
        }
        br.close();
        socket.close();
        serverSocket.close();
    }
}

运行结果:

练习四:简单的发送和接收数据

  • 客户端: 发送数据,接收服务器反馈
  • 服务器端: 接收数据,给出反馈

客户端:

import java.io.*;
import java.net.Socket;

/**
 * @Author {那蓝桉}
 * @Date: 2023/04/08/ 14:36
 * @description 客户端: 发送数据,接收服务器反馈
 */
public class TCP_Client3 {
    public static void main(String[] args) throws IOException {
        // 创建客户端的Socket对象(Socket)
        Socket socket = new Socket("localhost",1122);
        // 获取输出流,写数据
        PrintWriter pw = new PrintWriter(socket.getOutputStream());
        pw.println("hello");
        pw.flush();
        socket.shutdownOutput();

        //接收服务器反馈
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;
        while((line=br.readLine())!=null){
            System.out.println(line);
        }
        //释放资源
        br.close();
        pw.close();
        socket.close();
    }
}

服务器端:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Author {那蓝桉}
 * @Date: 2023/04/08/ 14:36
 * @description 服务器: 接收数据,给出反馈
 */
public class TCP_Server3 {
    public static void main(String[] args) throws IOException {
        // 创建服务器端的Socket对象(ServerSocket)
        ServerSocket serverSocket = new ServerSocket(1122);
        Socket socket = serverSocket.accept();
        System.out.println("等待接收");
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;
        while((line= br.readLine())!=null){
            System.out.println(line);
        }

        //做出反馈
        PrintWriter pw = new PrintWriter(socket.getOutputStream());
        pw.println("数据已收到");
        pw.flush();
        //释放资源
        pw.close();
        br.close();
        socket.close();
        serverSocket.close();
    }
}

运行结果:

练习五:上传文件

  • 客户端:数据来自于文本文件或者图片

  • 服务器端:接收到的数据写入文本文件或者图片

客户端:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;

public class TCP_Client4 {
    public static void main(String[] args) throws IOException {
        //建立连接
        Socket socket = new Socket("localhost",1122);
        //输入流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:/picture/cat.jpg"));
        //输出流
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        //读取数据
        int b;
        while((b=bis.read())!=-1){
            bos.write(b);
        }
        bos.close();
        bis.close();
        socket.close();
        System.out.println("发送成功");
    }
}

服务器端:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TCP_Server4 {
    public static void main(String[] args) throws IOException {
        //监听指定端口
        ServerSocket serverSocket = new ServerSocket(1122);
        //阻塞式接收
        Socket socket = serverSocket.accept();
        //输入流,获取客户端socket中的数据
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        //输出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:/cat.jpg"));
        int b;
        while((b=bis.read())!=-1){
            bos.write(b);
        }
        bos.close();
        bis.close();
        socket.close();
        serverSocket.close();
        System.out.println("上传成功");
    }
}

运行结果:

练习六:上传文件,并得到服务器的反馈

  • 客户端:数据来自于文本文件或者图片,接收服务器反馈
  • 服务器:接收到的数据写入文本文件或者图片,给出反馈

出现问题: 程序一直等待

原因:读数据的方法是阻塞式的

解决方法

1、自定义结束标记;

2、使用shutdownOutput() :禁用此套接字的输出流(推荐)

客户端:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;

/**
 * @Author {那蓝桉}
 * @Date: 2023/04/08/ 15:11
 * @description 客户端:数据来自于文本文件或者图片,接收服务器反馈
 */
public class TCP_Client5 {
    public static void main(String[] args) throws IOException {
        //TCP需要建立连接
        Socket socket = new Socket("localhost",1122);
        //读取流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:/picture/cat.jpg"));
        //输出流
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        //读取数据
        int b;
        while((b=bis.read())!=-1){
            bos.write(b);
            bos.flush();
        }
        System.out.println("发送成功");
//        bos.close();不能用
        socket.shutdownOutput();//仅仅关闭输出流
        BufferedInputStream bis2 = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = new byte[1024];
        int len = bis2.read(bytes);
        String str = new String(bytes,0,len);
        System.out.println("收到服务器消息:"+str);
        socket.close();

    }
}

服务器端:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Author {那蓝桉}
 * @Date: 2023/04/08/ 15:11
 * @description 服务器:接收到的数据写入文本文件或者图片,给出反馈
 */
public class TCP_Server5 {
    public static void main(String[] args) throws IOException {
        //监听指定端口
        ServerSocket serverSocket = new ServerSocket(1122);
        System.out.println("准备就绪");
        //阻塞式接收
        Socket socket = serverSocket.accept();
        //获取客户端socket的数据
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        //输出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:/cat.jpg"));
        //读取数据
        int b;
        while((b=bis.read())!=-1){
            bos.write(b);
            bos.flush();
        }
        bos.close();

        //服务器响应:向客户端发消息
        BufferedOutputStream bos2 = new BufferedOutputStream(socket.getOutputStream());
        bos2.write("上传完毕".getBytes());
        bos2.close();
        socket.close();
        serverSocket.close();
        System.out.println("通信结束");
    }
}

运行结果:

练习七:服务器可以接收多个客户端上传的文件,线程封装

  • 客户端: 数据来自文本文件或者图片,接收服务器反馈

  • 服务器:接收到的数据写入文本文件或者图片,给出反馈,代码用线程封装,为每一个客户端开启一个线程

客户端:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;

public class TCP_Client6 {
    public static void main(String[] args) throws IOException {
        //TCP需要建立连接
        Socket socket = new Socket("localhost",1122);
        //读取流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:/picture/cat.jpg"));
        //输出流
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        //读取数据
        int b;
        while((b=bis.read())!=-1){
            bos.write(b);
            bos.flush();
        }
        System.out.println("发送成功");
//        bos.close();不能用
        socket.shutdownOutput();//仅仅关闭输出流
        BufferedInputStream bis2 = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = new byte[1024];
        int len = bis2.read(bytes);
        String str = new String(bytes,0,len);
        System.out.println("收到服务器消息:"+str);
        socket.close();

    }
}

服务器端:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class ThreadServer extends Thread{
    private Socket socket;

    public ThreadServer(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {//获取客户端socket的数据
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
            LocalDateTime localDateTime = LocalDateTime.now();
            String fileName = localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssms"));
            System.out.println(fileName);
            //输出流
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:/"+fileName+".jpg"));
            //读取数据
            int b;
            while((b=bis.read())!=-1){
                bos.write(b);
                bos.flush();
            }
            bos.close();

            //服务器响应:向客户端发消息
            BufferedOutputStream bos2 = new BufferedOutputStream(socket.getOutputStream());
            bos2.write("上传完毕".getBytes());
            bos2.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TCP_Server6 {
    /**
     * 服务端接收客户端发来的文件
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        //监听指定端口
        ServerSocket serverSocket = new ServerSocket(1122);
        System.out.println("准备就绪");
        while(true){
            Socket socket =serverSocket.accept();
            new ThreadServer(socket).start();
        }
    }
}

运行结果:

  

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值