`
yixiandave
  • 浏览: 140554 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

NIO学习笔记3(UDP)

阅读更多
经过仔细研究还是决定换回UDP协议(于是前面两天的代码滚蛋了)
NIO同样支持udp协议,不过相关的方法调用是有区别的

java的udp端口类是DatagramSocket
因此对应的nio channel类就是DatagramChannel

由于udp是一个无连接的协议,因此服务器端和客户端的代码基本相同。实际上服务器和客户端之间并没有太大区分。所以不存在ServerDatagramChannel这种玩意了,服务器端和客户端都是创建一个DatagramChannel。然后bind一个端口,注册Selector之后就可以打开监听了。

注意和SocketChannel的区别有以下几点:
接收数据:SocketChannel的方法是
ByteBuffer buffer = ByteBuffer.allocate(500);
int readCount = socketChannel.read(buffer);

虽然DatagramChannel也有read(ByteBuffer buffer)这个方法,但是直接调用只会抛出异常。

接收数据包的正确姿势如下:
ByteBuffer buffer = ByteBuffer.allocate(500);
InetSocketAddress = (InetSocketAddress)datagramChannel.receive(buffer);

此方法直接返回一个SocketAddress对象,包含了数据来源的地址和端口,在反馈数据的时候就有大用处了。于此同时,datagramChannel.getRemoteAddress()方法自然是不可能有正确结果的,没有连接是不会有Remote Address的啦

同理,发送数据包的姿势也变了
原来的方式是:
socketChannel.write(ByteBuffer.wrap("test data".getBytes()));

由于udp的无连接属性,此方法会让系统一头雾水的,我们需要加上发送的目标地址:
datagramChannel.send(ByteBuffer.wrap("test data".getBytes()),new InetAddressSocket("localhost",12345));

=======================我是傲娇的分割线================================
补充
另外,值的注意的是,在Android的开发包里,DatagramChannel的bind方法已被移除,大概是不希望某人使用一台android设备当服务器用
但是我又发现了一个connect方法,这个方法在jdk中也有,同样是传入一个SocketAddress参数。经过尝试后发现,这是android只能作为客户端的一个限定。connect方法传入的应该是服务器的地址和端口参数,调用这个connect后,android系统会自行打开一个未使用的随机端口作为发送端
这时候调用.write()方法同样可以将数据发出。注意如果这里依然调用send方法,send后的地址一定要与connect传入的地址相同,否则会报出地址不匹配的异常!

综上所述,DatagramChannel可以事先调用connect方法连接到服务器然后直接使用write发送数据
否则就必须使用send方法发送。
下图应该可以更清楚
connect(服务器地址)--------------write()|send()[send目标必须与connect目标相同]
bind(本地端口)-------------------send()[send目标可以是任意地址]

补充2
DatagramChannel不需要事先将SelectionKey的interestOps设置为OP_WRITE即可直接发送数据

=========================我才不是分割线呢==================================
注意的是与TCP基于字节流的协议不同,udp是以数据报为单位单独发送的,因此一个数据包的大小不应过大。
可通过的数据报大小由整个路径中最小的MTU决定。


[linux中可以使用ifconfig命令轻松查询到自己系统的MTU]

默认局域网MTU大小是1500字节,注意要自行减去IP数据报头20字节的占用,另外udp报头还有8个字节,也就是只有1472个字节是我们可以支配的。
超出MTU的部分会由系统进行分片处理,到达目标后再自动组装回来。但是由于udp不保证传输质量,一旦分片后某一片丢失会直接导致整个数据报被丢弃。尽管使用udp并不要求数据100%送达,但在数据完整度方面还是尽可能做到更好。
注意PPPOE/ADSL的MTU默认值是1492字节(可支配1464)
而Internet标准MTU是576字节(可支配548)
如果使用udp协议传输的数据需要经过外网,还是定义在548字节以内最佳

今天的总结就写到这里,如有谬误欢迎指正
====================
最终补充
Android慎用nio udp接收数据!!莫名其妙收不到数据报,到现在原因还没查出来。。准备客户端弃用nio了
  • 大小: 35.1 KB
分享到:
评论
1 楼 tonytony3 2014-12-30  
客户端弃用nio了?

相关推荐

    javaNIO学习笔记

    ### Java NIO 学习笔记 #### 一、概述 Java NIO (Non-Blocking IO,也称为 Java New IO),是 Java 对传统 IO 模型的一次重大改进,旨在提高程序处理大量并发连接的能力。NIO 的核心组件包括 Channels、Buffers 和 ...

    javaNIO学习笔记(csdn)————程序.pdf

    Java NIO 提供了多种通道,如FileChannel、DatagramChannel、SocketChannel和ServerSocketChannel,分别用于文件、UDP和TCP网络通信。 2. **缓冲区(Buffer)**:缓冲区是NIO中的核心概念,它是数据的容器。读取数据...

    Java+JDK6学习笔记

    本篇将围绕“Java+JDK6学习笔记”展开,探讨在JDK6环境下Java编程的核心知识点。 1. **JDK6概述**:JDK6是Oracle公司于2006年发布的Java平台标准版(Java SE)的一个重要版本,它的全称是Java SE 6,带来了许多新...

    林信良学习笔记HTML版

    【描述】提到"如果这本学习笔记你看懂了,那就证明 javase 你学会了",意味着这份笔记全面且深入,能够作为检验JavaSE学习成果的标准。JavaSE是Java平台的基础,包含用于开发桌面应用和服务器端应用的核心库和工具。...

    Java公司培训经典学习笔记

    Java公司培训经典学习笔记是针对Java编程语言进行深入学习的一份宝贵资料,涵盖了从基础到高级的诸多知识点,旨在帮助开发者提升技能,适应企业级项目开发的需求。以下将详细阐述这些笔记中的关键点: 1. **Java...

    nio相关知识学习

    博主分享的笔记可能还会深入讨论NIO与传统IO的差异、内存映射文件(MAPPED BUFFER)以及异步非阻塞I/O(AIO)等相关内容,这些都是Java开发者应当掌握的重要技能。 总之,NIO是Java中提升系统性能的重要工具,尤其...

    学习笔记 十分有用 java

    【Java学习笔记详解】 在Java的学习旅程中,基础至关重要。这份“学习笔记 十分有用 java”涵盖了J2SE(Java Standard Edition)的基础知识,旨在帮助读者深入理解这门广泛使用的编程语言。J2SE是Java的核心部分,...

    良葛格java学习笔记

    【标题】:“良葛格java学习笔记”是一个关于Java编程语言的学习资料集合,由作者林信良编写,旨在分享他的学习心得和实践经验。这个资源特别关注JDK 6.0的新特性和功能,帮助读者更好地理解和掌握这一版本的Java...

    Mina2.0学习笔记(完整版).doc

    Mina2.0是其一个重要的版本,提供了许多改进和新特性,使得开发者能够更轻松地处理网络通信任务,尤其是在Java NIO(Non-blocking Input/Output)环境下。 **1. Mina的异步事件驱动模型** Mina的核心设计理念是...

    网络编程-狂神说Java学习笔记

    "狂神说Java学习笔记"提供了深入理解和实践网络编程的宝贵资源。本笔记主要涵盖了以下几个关键知识点: 1. **Java网络编程基础**:Java通过Socket API提供了网络通信的能力。Socket代表了网络上的两个应用程序之间...

    java学习笔记4

    Java学习笔记第四部分主要涵盖了Java编程语言的深入学习内容,可能是继基础语法、面向对象编程之后的高级主题。"良葛格"作为编著者,可能以易懂且实用的方式阐述了这些概念。以下是根据标题和描述可能包含的知识点:...

    Java学习笔记,对初学者很有用

    这份“Java学习笔记”是为初学者准备的宝贵资源,它详细记录了学习Java过程中的重要概念和知识点。 首先,Java的基础知识是学习的起点。这包括了解Java的历史背景、JVM(Java虚拟机)的工作原理以及如何安装Java...

    NIO+Netty5视频教程与Netty源码剖析视频教程

    《NIO+Netty5视频教程与Netty源码剖析视频教程》是一份全面解析网络编程框架Netty的教育资源,旨在帮助学习者深入理解和应用NIO(非阻塞I/O)以及Netty5的核心技术。该教程分为两个主要部分,分别针对理论分析和实战...

    javase基础学习笔记

    本学习笔记将深入探讨JavaSE的基础知识,帮助你构建坚实的编程基础。 首先,我们从“javase学习笔记”开始。这部分内容可能涵盖了以下几个关键知识点: 1. **环境配置**:安装JDK(Java Development Kit),设置...

    郑志远的java学习笔记

    《郑志远的Java学习笔记》是一份详细记录了作者郑志远在深入学习Java编程过程中积累的知识点和实践经验的文档。这份笔记以其系统性、实用性以及深入浅出的讲解方式,成为了Java初学者和进阶者的重要参考资料。以下是...

    java学习笔记-老师的课程笔记

    Java学习笔记是初学者探索Java编程世界的宝贵资源。这份由老师精心整理的课程笔记涵盖了Java的基础到进阶知识,旨在帮助新手快速理解并掌握这门强大的面向对象编程语言。笔记内容可能包括但不限于以下方面: 一、...

    java基础学习笔记

    本Java基础学习笔记将深入探讨Java的核心概念和技术,帮助初学者建立起坚实的编程基础。 一、Java环境搭建 学习Java首先需要安装Java Development Kit(JDK),这是编写和运行Java程序所需的基本工具集。安装完成后...

Global site tag (gtag.js) - Google Analytics