网络编程服务器端接受数据比对不匹配的问题:

本文介绍了在网络编程中遇到的一个问题,即使用UDP进行通信时,服务器端无法正确识别客户端发送的'886'信号以退出接收循环。问题出在服务器端将接收到的byte数组直接转换为String时,由于byte数组长度超过实际数据长度,导致额外的字节被填充为null。为解决此问题,文章详细解释了如何通过调整String构造方法,指定偏移量和长度来正确解析数据,从而确保判断条件生效。
摘要由CSDN通过智能技术生成

网络编程服务器端接受数据比对不匹配的问题:

在网络编程中我们通常会用到验证用户输入或者文件的情况,在这个时候可能会遇到即使文本正确也比对失败的问题,如这次我做的一个一个简单的发送消息小程序(利用UDP实现)。

需求分析:

一:搭建好网络编程的框架(C/S模型)

二:在客户端接收客户输入,使用DatagramPacket,并通过send方法发送。

三:服务器接收文件,在使用DatagramPacket的receive读取文件后判断数据是否是字符串886。

项目开始:

客户端:

//Client端
public static void main(String[] args) throws IOException {
    //创建数据包套接字对象
    DatagramSocket ds=new DatagramSocket();
    //创建Scanner对象
    Scanner sc=new Scanner(System.in);
    int flag=0;
    //设置标志位,当标志位为0时持续接收消息,当标志位为1时退出循环
    while (flag==0){
        String s = sc.nextLine();
        //如果消息为886,发送消息、关闭数据包并将标志位设为1
        if (s.equals("886")){
            flag=1;
        }
        byte[] buf=s.getBytes();
        DatagramPacket dp=new DatagramPacket(buf,buf.length, InetAddress.getByName("172.20.20.17"),10000);
        ds.send(dp);
    }
    ds.close();
}

服务器端:

public static void main(String[] args) throws IOException {
        boolean flag=true;
    	//创建数据包套接字对象
        DatagramSocket ds=new DatagramSocket(10000);
    	//设置标志位,当标志位为true时持续接收消息,当标志位为false时退出循环
        while (flag){
            byte[] buf =new byte[1024];
            DatagramPacket dp=new DatagramPacket(buf,buf.length);
            //接收数据包
            ds.receive(dp);
            //解析数据包
            String s=new String(dp.getData());
            System.out.println(s);
            //如果数据为886退出循环
            if ("886".equals(s))
            {
                flag=false;
            }
        }
        ds.close();
}

但是在运行结束后发现,及时发送了886,服务器端也没有跳出接收循环。Debug后发现运行到判断语句后直接略过并没有执行将标志位归为的操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nIGAphf2-1618282608022)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20210412152019519.png)]

后期研究API发现,这是由于String的底层是字符数组,当用字符数据buf创建并设置其长度为1024时,用

String s=new String(dp.getData());

来直接将其转为为String对象,会把所有超长的字符空间置为null,此时再用

"886".equals(s)

去判断,则会判断失败。最后通过查看API文档了解到有

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A1bvPUxc-1618282608024)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20210412152929084.png)]

这个构造方法,可以通过设置偏移量和长度来避免这个问题,于是服务器端最后修改成这个样子。

public static void main(String[] args) throws IOException {
    boolean flag=true;
    //创建数据包套接字对象
    DatagramSocket ds=new DatagramSocket(10000);
    //设置标志位,当标志位为true时持续接收消息,当标志位为false时退出循环
    while (flag){
        byte[] buf =new byte[1024];
        DatagramPacket dp=new DatagramPacket(buf,buf.length);
        //接收数据包
        ds.receive(dp);
        //解析数据包
        String s=new String(dp.getData(),0,dp.getLength());
        System.out.println(s);
        //如果数据为886退出循环
        if ("886".equals(s))
        {
            flag=false;
        }
    }
    ds.close();
}
    if ("886".equals(s))
    {
        flag=false;
    }
}
ds.close();

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值