小白解说 UDP TCP 客户端服务端 发送接收数据 附详细代码~

udp

效果图如下:
服务端接收到客户端发的数据
在这里插入图片描述
客户端接收到服务端返回的数据
在这里插入图片描述

DatagramSocket

java使用DatagramSocket代表UDP协议的Socket,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。

DatagramSocket的构造器

  • DatagramSocket():创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、本机所有可用端口中随机选择的某个端口。
  • DatagramSocket(int prot):创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、指定端口。
  • DatagramSocket(int port, InetAddress laddr):创建一个DatagramSocket实例,并将该对象绑定到指定IP地址、指定端口。

通常在创建服务器时,创建指定端口的DatagramSocket实例–这样保证其他客户端可以将数据发送到该服务器。一旦得到了DatagramSocket实例之后,就可以通过如下两个方法来接收和发送数据。

接收数据

  • receive(DatagramPacket p):从该DatagramSocket中接收数据报。
  • send(DatagramPacket p):以该DatagramSocket对象向外发送数据报。

从上面两个方法可以看出,使用DatagramSocket发送数据报时,DatagramSocket并不知道将该数据报发送到哪里,而是由DatagramPacket自身决定数据报的目的地。就像码头并不知道每个集装箱的目的地,码头只是将这些集装箱发送出去,而集装箱本身包含了该集装箱的目的地。

DatagramPacket的构造器

  • DatagramPacket(byte[] buf,int length):以一个空数组来创建DatagramPacket对象,该对象的作用是接收DatagramSocket中的数据。
  • DatagramPacket(byte[] buf, int length, InetAddress addr, int port):以一个包含数据的数组来创建DatagramPacket对象,创建该DatagramPacket对象时还指定了IP地址和端口–这就决定了该数据报的目的地。
  • DatagramPacket(byte[] buf, int offset, int length):以一个空数组来创建DatagramPacket对象,并指定接收到的数据放入buf数组中时从offset开始,最多放length个字节。
  • DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):创建一个用于发送的DatagramPacket对象,指定发送buf数组中从offset开始,总共length个字节。

当Client/Server程序使用UDP协议时,实际上并没有明显的服务器端和客户端,因为两方都需要先建立一个DatagramSocket对象,用来接收或发送数据报,然后使用DatagramPacket对象作为传输数据的载体。通常固定IP地址、固定端口的DatagramSocket对象所在的程序被称为服务器,因为该DatagramSocket可以主动接收客户端数据。

在接收数据之前,应该采用上面的第一个或第三个构造器生成一个DatagramPacket对象,给出接收数据的字节数组及其长度。然后调用DatagramSocket 的receive()方法等待数据报的到来,receive()将一直等待(该方法会阻塞调用该方法的线程),直到收到一个数据报为止。代码如下

    // 创建一个接收数据的DatagramPacket对象  
    DatagramPacket packet=new DatagramPacket(buf, 256);  
    // 接收数据报  
    socket.receive(packet);   

在发送数据之前,调用第二个或第四个构造器创建DatagramPacket对象,此时的字节数组里存放了想发送的数据。除此之外,还要给出完整的目的地址,包括IP地址和端口号。发送数据是通过DatagramSocket的send()方法实现的,send()方法根据数据报的目的地址来寻径以传送数据报。如下代码所示:

// 创建一个发送数据的DatagramPacket对象  
DatagramPacket packet = new DatagramPacket(buf, length, address, port);  
// 发送数据报  
socket.send(packet);

udp客户端发送数据

package udp;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;

public class client {
    public static void main(String args[]){
        String host="localhost";
        if(args.length==1)
            host=args[0];
        DatagramPacket dgp1;
        DatagramSocket s=null;
        try{
            s=new DatagramSocket();
            byte []buffer;//用来存储发送的数据
            buffer = new String("hello").getBytes();//字符串转化数组
            //将主机名转变为InetAddress类对象,此对象存储有ip对象和地址
          InetAddress ia=InetAddress.getByName("127.0.0.1");
            //创建一个DatagramPacket对象来封装字节数组的指针以及目标地址信息,目标地址包含了ip和端口号
            DatagramPacket dgp=new DatagramPacket(buffer,buffer.length,ia,9369);
            s.send(dgp);
            byte []buffer2=new byte[50];
            //创建一个对象来封装返回来的数据
            dgp1=new DatagramPacket(buffer2,buffer.length,ia,9369);
            s.receive(dgp1);
            System.out.println("server:"+new String(dgp1.getData()));
        }
        catch(IOException e){
            System.out.println(e.toString());
        }
        finally{
            if(s!=null)
                s.close();
        }
    }
}

注意 tcp udp 端口号需要在入站规则里面添加 如果用到服务器需要在阿里云设置端口

udp服务端接收数据

package udp;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class server {

    public static void main(String args[])throws IOException {
        System.out.println("Server starting...\n");
        try {
            //在端口号9000上创建套接字,从用户程序发送包到这个端口
            DatagramSocket s = new DatagramSocket(9359);
            byte[] data = new byte[200];
            DatagramPacket dgp = new DatagramPacket(data, data.length);
          
            while (true) {
                Date date = new Date();
                String nowTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
                s.receive(dgp);
                System.out.println("地址:" + dgp.getAddress());
                System.out.println("client:" + new String(data));
                System.out.println(nowTime);
//                发送数据
                s.send(dgp);
            }
        } catch (Exception e) {
            e.printStackTrace();
     }
    }
    }

参考连接:https://www.cnblogs.com/0Nullptr/articles/6718179.html
https://blog.csdn.net/green703338130/article/details/79638160

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值