0


简要分析网络编程——UDP编程

计算机网络是指两台或更多的计算机组成的网络,在同一个网络中,任意两台计算机都可以直接通信,因为所有计算机都需要遵循同一种网络协议。网络编程中有很多协议,如,TCP协议、UDP协议。顾名思义,UDP编程就是以UDP协议为基础的编程。

和TCP编程相比,UDP编程就简单得多,因为UDP没有创建连接,数据包也是一次收发一个,所以没有流的概念。

在Java中使用UDP编程,仍然需要使用Socket,因为应用程序在使用UDP时必须指定网络接口(IP地址)和端口号。注意:UDP端口和TCP端口虽然都使用0~65535,但他们是两套独立的端口,即一个应用程序用TCP占用了端口1234,不影响另一个应用程序用UDP占用端口1234。

在服务器端,使用UDP也需要监听指定的端口。Java提供了DatagramSocket来实现这个功能,服务器端首先要监听一个指定的端口(如1234端口),如果没有其他应用程序占据这个端口,那么监听成功,我们就使用一个无限循环来处理收到的UDP数据包,若要接收一个packet数据包,我们需要根据接收数据的大小创建一个byte[ ]缓冲区,然后通过Dategrampacket实现接收;假设我们收取到的是一个String,那么,通过DatagramPacket返回的packet.getOffset()和packet.getLength()确定数据在缓冲区的开始位置和结束位置,在下面的代码中,我们需要把接收到的字节数组转化为字符串,然后作为key(键)在创建的map中得到相应的value(值),因为怕发送至客户端时出现空指针异常,我们可以在得到value(值)后,可以做一个判断,如果值为null,则给value赋值为一个提示,让客户端重新输入一个map中存在的值,然后进行后面的发送操作。一般当服务器收到一个DatagramPacket后,通常必须立刻回复一个或多个UDP包,因为客户端地址在DatagramPacket中,每次收到的DatagramPacket可能是不同的客户端,如果不回复,客户端就收不到任何UDP包。 发送UDP包也是通过DatagramPacket实现的。发送UDP数据包时,我们需要把从map中得到的字符串利用*.getBytes()方法变成一个字符串数组,然后通过DatagramPacket发送至客户端。具体代码实现如下:

package com.hpc.wyj02;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.HashMap;
import java.util.Map;

/**
 * 服务器
 * @author 我
 *
 */
public class Demo02 {
    public static void main(String[] args) {
        
        Map<String, String> map=new HashMap<String, String>(){
            {
                put("one","一");
                put("two","二");
                put("three","三");
                put("four","四");
            }
        };
        //服务器端监听1234端口
        try (DatagramSocket serverSocket = new DatagramSocket(1234)) {
            while(true) {
                //准备“空”数据包
                byte[] buff=new byte[1024];   //原始的字节数组
                DatagramPacket packet=new DatagramPacket(buff, buff.length);
                
                //读取(客户端发送的英文单词)
                //接收数据包
                serverSocket.receive(packet);
                
                //获取数据包中的“数据”(字节数组):packet.getData()
                //获取数据包中的“读取位置”(int类型):packet.getOffset()
                //获取数据包中的“长度”:packet.getLength()
                String s=new String(packet.getData(), packet.getOffset(),         
                                  packet.getLength());
                System.out.println("来自客户端的单词:"+s);
                
                String chinese=map.get(s);
                if(chinese==null) {
                    chinese="请重新输入!";
                }
                byte[] chinesebuff=chinese.getBytes();
            
                packet.setData(chinesebuff);
                serverSocket.send(packet);

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

在客户端,和服务器端相比,客户端使用UDP时,只需要直接向服务器端发送UDP包,然后接收返回的UDP包。首先,客户端需要创建一个DatagramSocket对象,客户端创建DatagramSocket实例时并不需要指定端口,而是由操作系统自动指定一个当前未使用的端口。紧接着,调用setSoTimeout(1000)设定超时1秒,意思是后续接收UDP包时,等待时间最多不会超过1秒,否则在没有收到UDP包时,客户端会无限等待下去。这一点和服务器端不一样,服务器端可以无限等待,因为它本来就被设计成长时间运行。注意到客户端的DatagramSocket还调用了一个connect()方法“连接”到指定的服务器端。这个connect()方法不是真连接,它是为了在客户端的DatagramSocket实例中保存服务器端的IP和端口号,确保这个DatagramSocket实例只能往指定的地址和端口发送UDP包,不能往其他地址和端口发送。这么做不是UDP的限制,而是Java内置了安全检查。如果客户端希望向多个不同的服务器发送UDP包,那么它必须创建多个DatagramSocket实例。后续的收发数据和服务器端是一致的。通常来说,客户端必须先发UDP包,因为客户端不发UDP包,服务器端就根本不知道客户端的地址和端口号。如果客户端认为通信结束,就可以调用disconnect()断开连接。注意:disconnect()也不是真正地断开连接,它只是清除了客户端DatagramSocket实例记录的远程服务器地址和端口号.这样,DatagramSocket实例就可以连接另一个服务器端。客户端的实现代码如下:

package com.hpc.wyj02;

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

public class Demo01 {
    /**
     * 客户端
     * @param args
     */
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        while(true) {
            String s=input.nextLine();   //英文单词
            if(s.equals("over")) {
                System.out.println("运行完毕!");
                break;
            }
            //创建基于UDP协议的DatagramSocket对象
            try (DatagramSocket cilentSocekt = new DatagramSocket()) {
                //timeout超时
                cilentSocekt.setSoTimeout(20000);
                //连接服务器(服务器IP和端口)
                cilentSocekt.connect(new InetSocketAddress("192.168.0.104",1234));
                //发送(向服务器发送一个英文单词)
                
                byte[] buff=s.getBytes();   //获取英文单词字符串的字节数组
                
                //封装成DatagramPacket对象(数据包)
                DatagramPacket cilentPacket=new DatagramPacket(buff,buff.length);
                //发送数据包
                cilentSocekt.send(cilentPacket);
                
                byte[] resultbuff=new byte[1024];
                DatagramPacket resultPacket=new DatagramPacket(resultbuff, 
                                                 resultbuff.length);
                cilentSocekt.receive(resultPacket);
                String result=new String(resultPacket.getData(), 
                             resultPacket.getOffset(), resultPacket.getLength());
                System.out.println("来自服务器的回答:"+result);
            } catch (IOException e) {
                e.printStackTrace();
            }
            
        }
    }

}
标签: 大数据 java java-ee

本文转载自: https://blog.csdn.net/weixin_51669424/article/details/125831639
版权归原作者 望远雾 所有, 如有侵权,请联系我们删除。

“简要分析网络编程&mdash;&mdash;UDP编程”的评论:

还没有评论