网络编程UDP

UDP协议

特点:

1.面向无连接的传输层协议

       (1)UDP协议在传输报文之前不需要在通信双方建立连接 因此减少了协议开销与传输延迟

         (2)UDP对报文除了提供校验和之外几乎没有提供其他的保证数据传输可靠性的措施

        (3)如果UDP协议检查出收到的分分组出错 它就丢弃这个分组 即不确认也不通知发送端和要求重发

2. 面向报文的传输层协议

        (1)UDP协议对于应用程序提交的报文,在添加了UDP头部,构成一个TPDU之后就向下提交给IP层

        (2)UDP协议对应用程序提交的报文既不合并也不拆分 而是保留原来的报文长度和格式。接收端将发送端提交发送的报文原封不动的提交给接收端应用程序。所以使用UDP协议时 应用程序要选择合适长度的报文

        (3)如果应用程序提交的报文太短 则协议开销相对较大 如果太长 则UDP协议向IP层提交的TPDU可能在IP层被分片 这会降低协议效率

UDP是适合实时语音与视频传输的传输层协议

UDP接收端:udpsender

 public static void main(String[] args)  { 
    	DatagramSocket socket=null;
    	try {
    		//通过DatagramSocket对象创建UDP
			socket=new DatagramSocket();
			//确定数据源 分装成数据包  指定数据源大小 和 接收端的ip 端口
			byte[] buf="UDP bao wen lai le".getBytes();
			DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),20000);
			//通过socket套接字将数据包发送出去 通过send方法
			socket.send(dp);
			//关闭资源
			socket.close();
		} catch (SocketException e) {
			e.printStackTrace();
		} 
    	catch (UnknownHostException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
    	//关闭资源
		socket.close();
    }   
UDP接收端:udpreceiver
public static void main(String[] args)  { 
    	DatagramSocket socket=null;
    	try {
    		//通过DatagramSocket对象创建UDP 监控端点
			socket=new DatagramSocket(20000);
			//定义数据包 来存储接受的数据
			byte[] buf=new byte[1024];
			DatagramPacket dp=new DatagramPacket(buf,buf.length);
			//socket用receive方法将数据存入数据包中
			socket.receive(dp);
			
			//通过数据包的方法获取数据包中的数据
			String ip=dp.getAddress().getHostAddress();
			String data=new String(dp.getData(),0,dp.getLength());
			int port=dp.getPort();
			System.out.println("ip: "+ip+" data: "+data+" port: "+port);
			//关闭资源
			socket.close();
		} catch (SocketException e) {
			e.printStackTrace();
		} 
    	catch (UnknownHostException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
    	//关闭资源
		socket.close();
    }

编译然后运行


注意:两个编译完成后 先运行UDPReciver 然后在运行UDPSender

运行出现Could not find or load main class。 这个参考:https://stackoverflow.com/questions/18093928/what-does-could-not-find-or-load-main-class-mean


看到运行结果可能很好奇47242 和50117是什么? 它们是发送方的端口。你也可以指定发送方的端口。

socket=new DatagramSocket(8888);

在发送方里是指定发送端口 在接收方是监听端口。

如果不指定端口发送 时 为什么发送的端口不一样 ? 即为什么都是47242 而变成50117? 因为运行结束后这个端口还在被占用着所以程序需要另外一个端口。

聊天:

public class ChatDemo {
	public static void main(String[] args) throws Exception{
		DatagramSocket send=new DatagramSocket();
		DatagramSocket rece=new DatagramSocket(20000);
		new Thread(new Send(send)).start();
		new Thread(new Send(rece)).start();
	}
}

接收方:

public class Recive implements Runnable{
	private DatagramSocket ds;
	private Recive(DatagramSocket ds){
		this.ds=ds;
	}
	public void run() {
		try{
			while(true){
				byte[] buf=new byte[1024];
				DatagramPacket dp=new DatagramPacket(buf,buf.length);
				ds.receive(dp);//阻塞方法 所以上面的while不会死循环
				String ip=dp.getAddress().getHostAddress();
				String data=new String(dp.getData(),0,dp.getLength());
				int port=dp.getPort();
				System.out.println("ip: "+ip+" data: "+data+" port: "+port);
			}
		}catch(Exception e){
			throw new RuntimeException("接收失败");
		}
	}

}

发送方:

public class Send implements Runnable{
	private DatagramSocket ds;
	public Send(DatagramSocket ds){
		this.ds=ds;
	}
	public void run() {
		BufferedReader buff=new BufferedReader(new InputStreamReader(System.in));
		String line=null;
		try {
			while((line=buff.readLine())!=null){
				if("886".equals(line))
					break;
				byte[] buf=line.getBytes();//下面ip的最后以为255广播 给该局域网
				DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.xx.255"),20000);
				ds.send(dp);
			}
		} catch(Exception e){
			throw new RuntimeException("发送失败");
		}
	}

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值