Java网络通信UDP

目录

网络通信基础

UDP通信

服务器

1.想要使用UDP通信 要先打开DatagramSocket文件 端口号可以手动指定或系统随机分配

2.阻塞等待接收客户端数据;创建DatagramPacket接收客户端传来的数据

3.处理客户端传来的数据,并进行业务处理(这里只演示UDP通信 所以只是回传数据)

4.处理数据成DatagramPacket并发送数据给客户端

整体代码

客户端

1.创建DatagramSocket (这里客户端端口号系统分配即可,不允许和服务器同一端口号)

2.客户端接收用户的数据

3.处理用户数据成DatagramPacket 指定要发送服务器的地址与端口号

4.发送数据给客户端

5.阻塞等待服务器响应

6.处理服务器响应的数据

7.显示数据给用户

整体代码

继承服务器代码,重写业务代码即可


网络通信基础

  1. 物理层:网络通信的基础设施                                    运快递的公路
  2. 数据链路层:两个相邻的节点之间如何传输               两个集散点之间的传输
  3. 网络层:两个点之间的路径规划                                 物流公司规划快递的路径
  4. 传输层:两个点之间的通信(不考虑路径规划)        卖家发货 只考虑起点和终点
  5. 应用层:数据传输过去之后 如何使用                         快递拿到之后如何使用

网络编程的主要工作写应用层的代码,处理应用层的协议数据

从5->1往下传输 每次传输都会依次添加报头 称为封装    QQ1发送

从1->5往上传输 每次传输都会解析去掉报头                   QQ2接收

传输层提供两种协议

TCP:有连接,可靠传输,面向字节流,全双工

UDP:无连接,不可靠传输,面向数据包,半双工

可靠传输:数据对方有没有接收到,发送方有感知;打电话就是可靠的,可以知道对方有没有听到。

不可靠传输:数据对方有没有接收到,不管,也不知道;微信就是不可靠,不知道对方有没有看到我的消息。

全双工:双向通信 可以A->B B->A 同时进行

半双工:单向通信 A->B或者B->A 同时只允许一个进行

程序要进行网络通信,需要一个端口号(客户端与服务器的端口号不能相同!)

端口号相当于用来在网络上区分进行的身份标识符

分配端口号有 1.手动指定 2.系统自动分配

UDP通信

UDP的Socket API

DatagramSocket和DatagramPaclet 核心类

socket类本质相当于文件 构造一个DatagramSock对象,相当于打开了一个内核中的socket文件

打开后就可以传输数据了

传输数据已 DatagramPacket为基本单位

InetSocketAddress类 IP地址+端口号

send发送数据 receive接收数据 close关闭数据

DatagramOacket 表示一个UDP数据报 UDP是面向数据报的协议

服务器

1.想要使用UDP通信 要先打开DatagramSocket文件 端口号可以手动指定或系统随机分配

    //想要使用UDP服务器 要打开一个文件
    private DatagramSocket socket=null;

    //创建对象
    //服务器IP和端口号是提供给客户端 方便客户端知道地址发送过来
    public Test1(int port) throws SocketException {
        socket=new DatagramSocket(port);//创建实例  绑定进程端口号

2.阻塞等待接收客户端数据;创建DatagramPacket接收客户端传来的数据

            DatagramPacket datagramPacket=new DatagramPacket(new byte[4096],4096);
            //客户端发来的请求放到参数datagramPacket  输出性参数
            System.out.println("我正在等待!");
            socket.receive(datagramPacket);//阻塞等待 客户端发起请求
            System.out.println("服务器接收到数据");

3.处理客户端传来的数据,并进行业务处理(这里只演示UDP通信 所以只是回传数据)

//把传来的数据构造成数据 1.获取数据 从0开始构造 构造到数据结尾
            String request=new String(datagramPacket.getData(),0,datagramPacket.getLength());
            System.out.println("接收到的数据:"+request);
            //处理业务
            String requst=process(request);
            System.out.println("服务器处理数据");

 public String process(String s){
        return s;
    }

4.处理数据成DatagramPacket并发送数据给客户端

//要传回客户端也要把数据构造成DatagramPacket
            //把string构造到byte字节  1.字节数据,2.字节长度 3.客户端的id+客户端的端口号
            DatagramPacket datagramPackets=new DatagramPacket(request.getBytes(),request.getBytes().length,datagramPacket.getSocketAddress());
            //发送数据
            socket.send(datagramPackets);
            System.out.println("服务器发送数据成功");
            System.out.printf("[地址:%s:端口号:%d] 发来数据:%s 服务器响应数据:%s\n",datagramPacket.getAddress().toString(),datagramPacket.getPort(),request,requst);

整体代码

package DemoUDP;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

//服务端
public class Test1 {
    //想要使用UDP服务器 要打开一个文件
    private DatagramSocket socket=null;

    //创建对象
    //服务器IP和端口号是提供给客户端 方便客户端知道地址发送过来
    public Test1(int port) throws SocketException {
        socket=new DatagramSocket(port);//创建实例  绑定进程端口号
    }

    public void start() throws IOException {
        System.out.println("启动服务器");
        while (true){
            //创建一个DatagramPacket(创建缓存区,缓存区长度)用来接收客户端发来的请求
            DatagramPacket datagramPacket=new DatagramPacket(new byte[4096],4096);
            //客户端发来的请求放到参数datagramPacket  输出性参数
            System.out.println("我正在等待!");
            socket.receive(datagramPacket);//阻塞等待 客户端发起请求
            System.out.println("服务器接收到数据");
            //把传来的数据构造成数据 1.获取数据 从0开始构造 构造到数据结尾
            String request=new String(datagramPacket.getData(),0,datagramPacket.getLength());
            System.out.println("接收到的数据:"+request);
            //处理业务
            String requst=process(request);
            System.out.println("服务器处理数据");

            //要传回客户端也要把数据构造成DatagramPacket
            //把string构造到byte字节  1.字节数据,2.字节长度 3.客户端的id+客户端的端口号
            DatagramPacket datagramPackets=new DatagramPacket(request.getBytes(),request.getBytes().length,datagramPacket.getSocketAddress());
            //发送数据
            socket.send(datagramPackets);
            System.out.println("服务器发送数据成功");
            System.out.printf("[地址:%s:端口号:%d] 发来数据:%s 服务器响应数据:%s\n",datagramPacket.getAddress().toString(),datagramPacket.getPort(),request,requst);
        }
    }
    public String process(String s){
        return s;
    }

    public static void main(String[] args) throws IOException {
        //端口号范围 0--65535 1024以下的端口是系统用的  尽量用1024以上 65535以下
        Test1 test1=new Test1(8080);
        test1.start();
    }
}

客户端

1.创建DatagramSocket (这里客户端端口号系统分配即可,不允许和服务器同一端口号)

DatagramSocket Socket=null;

    //客户端端口号需要系统自动分配 不能指定与服务器端口号一样,不然会抢占服务器端口号 导致后启动的一端无法启动
    public Test2() throws SocketException {
        Socket=new DatagramSocket();
    }

2.客户端接收用户的数据

Scanner scanner=new Scanner(System.in);
            System.out.println("客户端输入数据:>");
            String Data=scanner.nextLine();

3.处理用户数据成DatagramPacket 指定要发送服务器的地址与端口号

//处理用户数据
            //1.把string类型处理成byte字节数据 datagramPacket类型 里面附带发送地址和发送对方的端口号
            DatagramPacket datagramPacket=new DatagramPacket(Data.getBytes(),Data.getBytes().length, InetAddress.getByName("127.0.0.1"),8080);
            System.out.println("客户端处理数据");

4.发送数据给客户端

 //发送数据
            Socket.send(datagramPacket);
            System.out.println("客户端发送数据");

5.阻塞等待服务器响应

//阻塞等待服务器的响应数据
            DatagramPacket datagramPackets=new DatagramPacket(new byte[1024],1024);
            Socket.receive(datagramPackets);
            System.out.println("客户端接收服务器响应数据");

6.处理服务器响应的数据

//处理服务器响应的数据
            String Datas=new String(datagramPackets.getData(),0,datagramPackets.getLength());
            System.out.println("客户端处理数据");

7.显示数据给用户

System.out.printf("服务器响应数据:%s\n",Datas);

整体代码

package DemoUDP;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

//客户端
public class Test2 {
    DatagramSocket Socket=null;

    //客户端端口号需要系统自动分配 不能指定与服务器端口号一样,不然会抢占服务器端口号 导致后启动的一端无法启动
    public Test2() throws SocketException {
        Socket=new DatagramSocket();
    }

    public void start() throws IOException {
        while (true){
            //接收用户数据
            Scanner scanner=new Scanner(System.in);
            System.out.println("客户端输入数据:>");
            String Data=scanner.nextLine();

            //处理用户数据
            //1.把string类型处理成byte字节数据 datagramPacket类型 里面附带发送地址和发送对方的端口号
            DatagramPacket datagramPacket=new DatagramPacket(Data.getBytes(),Data.getBytes().length, InetAddress.getByName("127.0.0.1"),8080);
            System.out.println("客户端处理数据");

            //发送数据
            Socket.send(datagramPacket);
            System.out.println("客户端发送数据");

            //阻塞等待服务器的响应数据
            DatagramPacket datagramPackets=new DatagramPacket(new byte[1024],1024);
            Socket.receive(datagramPackets);
            System.out.println("客户端接收服务器响应数据");

            //处理服务器响应的数据
            String Datas=new String(datagramPackets.getData(),0,datagramPackets.getLength());
            System.out.println("客户端处理数据");

            //显示处理后的数据给用户
            System.out.printf("服务器响应数据:%s\n",Datas);
        }
    }

    public static void main(String[] args) throws IOException {
        Test2 test2=new Test2();
        test2.start();
    }
}

继承服务器代码,重写业务代码即可

package DemoUDP;

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

public class Test3 extends Test1{

    public Test3(int port) throws SocketException {
        super(port);
    }

    @Override
    public String process(String s) {
        Map<String,String> dic=new HashMap<String,String>();

        dic.put("cat","猫");

        return dic.getOrDefault(s,"此单词还未更新");
    }

    public static void main(String[] args) throws IOException {
        Test3 test3=new Test3(8080);
        test3.start();
    }


}

指定客户端多开

之后就可以同时运行多个客户端访问服务器

  • 25
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java可以通过TCP和UDP协议实现网络通信。其中,TCP协议提供面向连接的、可靠的数据传输服务,而UDP协议则提供无连接的、不可靠的数据传输服务。 下面是Java实现TCP网络通信的例子: ```java // 服务器端 ServerSocket serverSocket = new ServerSocket(8888); Socket socket = serverSocket.accept(); InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String message = null; while ((message = br.readLine()) != null) { System.out.println("接收到客户端消息:" + message); } br.close(); socket.close(); serverSocket.close(); // 客户端 Socket socket = new Socket("127.0.0.1", 8888); OutputStream os = socket.getOutputStream(); PrintWriter pw = new PrintWriter(os); pw.write("Hello, server!"); pw.flush(); socket.shutdownOutput(); socket.close(); ``` 下面是Java实现UDP网络通信的例子: ```java // 服务器端 DatagramSocket serverSocket = new DatagramSocket(8888); byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); serverSocket.receive(packet); String message = new String(packet.getData(), 0, packet.getLength()); System.out.println("接收到客户端消息:" + message); serverSocket.close(); // 客户端 DatagramSocket clientSocket = new DatagramSocket(); String message = "Hello, server!"; byte[] buffer = message.getBytes(); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("127.0.0.1"), 8888); clientSocket.send(packet); clientSocket.close(); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值