JAVA UDP网络编程学习笔记
一、UDP网络编程概述
采用TCP协议通信时,客户端的Socket必须先与服务器建立连接,连接建立成功后,服务器端也会持有客户端连接的Socket,客户端的Socket与服务器端的Socket是对应的,它们构成了两个端点之间的虚拟通信链路。与TCP通信不同,UDP是面向无连接的、不可靠的基于数据包的传输协议。即应用进程(或程序)在使用UDP协议之前,不必先建立连接。自然,发送数据结束时也没有连接需要释放。因此,减少了开销和发送数据之前的延时。UDP也采用端口来区分进程。
在java中,java.net.DatagramSocket负责接收和发送UDP数据报文,java.net.DatagramPacket表示UDP数据报。每个DatagramSocket与一个数据报套接字(包括本地主机的IP地址和本地UDP端口)绑定,每个DatagramSocket可以把UDP数据报发送给任意一个远程DatagramSocket,也可以接收来自任意一个远程DatagramSocket的数据报。在UDP数据报中包含了目的地址信息,DatagramSocket可以根据该信息把数据报发送的目的地。
UDP协议是无连接的协议。客户端的DatagramSocket与服务端DatagramSocket不存在一一对应关系,两者无需建立连接,就能交换数据报。每个DatagramSocket对象都会与一个本地端口绑定,在此端口监听发送过来的数据报。在服务器程序中,一般由程序显示地为DatagramSocket指定本地端口。在客户程序中,一般由操作系统为DatagramSocket分配本地端口,这种端口也称为匿名端口。
二、关于DatagramSocket类和DatagramPacket类
DatagramSocket类的构造方法如下:
DatagramSocket()throws SocketException
作用:构造数据报套接字并将其绑定到本地主机上任何可用的端口。套接字将被绑定到INADDR_ANY地址,IP地址由内核来选择。
DatagramSocket(int port)throws SocketException
作用:创建数据报套接字并将其绑定到本地主机上的指定端口。套接字将被绑定到INADDR_ANY地址,IP地址由内核来选择。
DatagramSocket类的常用方法如表所示:
void send(DatagramPacket p) throws IOException | 发送一个UDP数据包。一个UDP数据包就是一个DatagramPacket对象 |
void receive(DatagramPacket p) throws IOException | 接收一个UDP数据包。一个UDP数据包就是一个DatagramPacket对象 |
void connect(InetAddress address,int port) | 将该UDPSocket变成连接型的UDPSocket |
void disconnect() | 将该UDPSocket变成一个非连接型的UDPSocket |
void close() | 关闭UDPSocket连接 |
其中,UDPSocket分为“连接型”与“非连接型”两种。默认UDPSocket是“非连接型”的,这个连接不是指向TCP那样进行三步握手,而只是将对方信息与自己关联在一起。
DatagramPacket类的对象代表了一个UDP数据报包。通过UDP发送数据时,先要根据发送的数据生成一个DatagramPacket对象,然后通过DatagramSocket对象的send()方法发送这个对象。接收时,先要根据要接收数据的缓冲区生成一个Datagrampacket对象,然后通过DatagramPacket对象的receive()方法接收这个对象的数据内容。
DatagramPacket类的构造方法分为两类:
一类是创建DatagramPacket对象用来接收数据报包;
另一类是创建DatagramPacket对象用来发送数据报包。
它们的区别是,用于发送数据报包的构造方法需要设置数据报包达到的目的地址,若是“连接型”UDP,则不需要设定目的地址,而用于接收数据报包的构造方法无须设定地址。
用于接收数据报包的构造方法如下:
DatagramPacket(byte[] buf,int length)
作用:由接收缓冲区生成一个DatagramPacket对象。buf表示保存传入数据报的缓冲区,length表示要读取的字节数。
DatagramPacket(byte[] buf,int offset,int length)
作用:构造DatagramPacket对象。用来接收长度为length的数据包,并在缓冲区中指定了偏移量。
用于发送数据报包的构造方法如下:
DatagramPacket(byte[] buf,int length,InetAddress address,int port)
作用:构造数据报包发送的对象,用来将长度为length的包发送到指定主机上的指定端口号。length参数要小于等于buf的长度。
DatagramPacket(byte[] buf,int offset,int length,InetAddress address,int port)
作用:构造数据报包发送的对象,用来将长度为length且偏移量为offset的包发送到指定主机上的指定端口号。length参数要小于等于buf的长度。
DatagramPacket类的常用方法如下表:
byte[] getData() | 返回DatagramPacket对象中包含的数据 |
int getLength() | 返回发送/接收数据的长度 |
int getOffset() | 返回发送/接收数据在byte[]中的偏移 |
InetAddress getAddress() | 返回对方的IP地址。用InetAddress对象表示 |
int getPort() | 返回对方的端口号 |
void setData(byte[] buf,int offset,int length) | 设置该对象中包含的数据 |
void setAddress(inetaddress iaddr) | 设置该对象中包含的IP地址 |
void setPort() | 设置该对象中包含的端口号 |
通过UDP发送/接收数据步骤:
发送数据,先要根据发送的数据生成一个DatagramPacket对象,并指定发送长度和接收数据的IP地址和端口号,然后通过DatagramSocket对象的send()方法发送这个对象。
接收数据,根据要接受收数据的缓冲区及大小生成一个DatagramPacket对象,然后通过DatagramSocket对象的receive()方法接收这个对象的数据内容。
三、UDP网络编程练习
练习代码:
package com.ItHeima.WeekAct; /**服务器**/ import java.net.*; public class ChatterClient extends Thread { private DatagramSocket socket;
private InetAddress address;
private byte[] buf = new byte[1000];
private DatagramPacket packet = new DatagramPacket(buf, buf.length);//创建要发送的数据包
private int id;//客户端id public ChatterClient(int id) {
this.id = id;
try {
socket = new DatagramSocket();//创建UDP套接字
address = InetAddress.getByName(null);//取得本地地址
} catch (SocketException e) {
System.out.println("can not open socket");
e.printStackTrace();
System.exit(1);
} catch (UnknownHostException e) {
System.out.println("Can not find host");
System.exit(1);
}
System.out.println("ChatterClient starting");
start();//之后调用run()
} public void run(){
try {
for(int i = 0 ; i < 25 ; i++){
String outMsg = "服务器你好,这是我客户端发过来的数据,请接收!" + id + ",消息" + i;//要发送到服务器的数据
socket.send(new DatagramPacket(outMsg.getBytes(),outMsg.getBytes().length, address, ChatterServer.INPORT));//打包数据并将其发送到指定地址+端口的服务端
socket.receive(packet);//接收服务端返回的数据包
String msg=new String(packet.getData(),packet.getOffset(),packet.getLength());//获取服务器返回的信息
String rcvd = "客户端--" + id +", 收到来自服务器的信息" + packet.getAddress() + "," + packet.getPort() + ":" + msg;//组合返回信息
System.out.println(rcvd);//输出到控制台
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);//出错退出
}
} public static void main(String[] args) {
for(int i = 0 ; i < 10 ; i ++ ){
new ChatterClient(i);
}
}
}
package com.ItHeima.WeekAct; /**服务器**/ import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException; public class ChatterServer { public static final int INPORT = 1711;//服务器端口
private byte[] buf = new byte[1000];
private DatagramPacket packet = new DatagramPacket(buf, buf.length);//创建数据包
private DatagramSocket socket;//UDP套接字
public ChatterServer(){
try{
socket = new DatagramSocket(INPORT);//启动套接字
System.out.println("Server started");
while(true){
socket.receive(packet);//接收数据包并将当前线程挂起
String msg=new String(packet.getData(),packet.getOffset(),packet.getLength());//获取客户端发送的信息
String rcvd ="服务器--收到来自客户端的信息:"+ msg+ ", from adddress:" + packet.getAddress() + ",port:" + packet.getPort();//解析数据包
System.err.println(rcvd);//打印数据信息
String returnMasg = "服务器返回信息:你好客户端,这是你发过来的数据:" + msg+",我将它原样返回";
DatagramPacket echo = new DatagramPacket(returnMasg.getBytes(), returnMasg.getBytes().length,packet.getAddress(), packet.getPort());//将接收到包重新包装称UDP数据包准备原封不动的返回给客户端
socket.send(echo);//反馈数据包
}
}catch (SocketException e) {
System.out.println("Can`t open socket");
System.exit(1);
}catch (IOException e) {
System.out.println("Communication error");
e.printStackTrace();
}
}
public static void main(String[] args) {
new ChatterServer();//运行服务器
}
}
运行结果:
JAVA UDP网络编程学习笔记的更多相关文章
- JAVA TCP网络编程学习笔记
一.JAVA网络编程概述 网络应用程序,就是在已实现网络互联的不同计算机上运行的应用程序,这些程序之间可以相互交换数据.JAVA是优秀的网络编程语言,Java网络编程的类库位于java.net包中.J ...
- Java Socket网络编程学习笔记(一)
0.前言 其实大概半年前就已经看过网络编程Socket的知识了(传统IO),但是因为长时间的不使用导致忘的一干二净,最近正好准备校招,又重新看了网络编程这一章, 是传统IO(BIO)相关的内容,故在此 ...
- 转 网络编程学习笔记一:Socket编程
题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...
- Java网络编程学习笔记
Java网络编程,我们先来看下面这一张图: 由图可得:想要进行网络编程,首先是服务器端通过ServerSocket对某一个端口进行监听.通过accept来判断是否有客户端与其相连.若成功连上,则通过r ...
- Java UDP网络编程 - 最简单示例
UDP也是网络通讯中的一个重要协议,与TCP区别可参见浅谈TCP/IP 和 UDP的区别,本文就对Java UDP通讯做一个简单例子介绍 服务端: package wyf; import java.i ...
- 网络编程学习笔记(二)基于TCP的Socket编程
1.Socket:英文意思插座.两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket. 2.Socket通常用来实现client-server(客户端 ...
- Linux C网络编程学习笔记
Linux C网络编程总结报告 一.Linux C 网络编程知识介绍: 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户端:(client) 在网络程序中, ...
- 网络编程学习笔记:Socket编程
文的主要内容如下: 1.网络中进程之间如何通信? 2.Socket是什么? 3.socket的基本操作 3.1.socket()函数 3.2.bind()函数 3.3.listen().connect ...
- 网络编程学习笔记一:Socket编程
“一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...
随机推荐
- LVM 创建分区扩展分区记录
LVM 原理 图片来自百度百科 测试环境centOS 7 LVM version: 2.02.115(2)-RHEL7 (2015-01-28) ...
- sqlite3 多线程和锁 ,优化插入速度及性能优化
一. 是否支持多线程? SQLite官网上的"Is SQLite threadsafe?"这个问答. 简单来说,从3.3.1版本开始,它就是线程安全的了.而iOS的SQLite ...
- ADO.NET 快速入门(八):处理 Errors
除了 Try/Catch 和 Exceptions 以外,新的 ADO.NET 数据框架也允许在 DataSet 的每行数据添加错误信息.如果 Updates 或者其他操作失败,SqlDataAdap ...
- 破解中国电信华为无线猫路由(HG522-C)自己主动拨号+不限电脑数+iTV
中国电信总是把好好的一个路由猫阉割过后放在我的E家套餐里到处兜售(垄断市场也就罢了,还有非常多霸王条款,比方必须使用它们的手机,同一时候最多多少台电脑上网等等),曾经破解过另外一个中国电信的路由猫,非 ...
- 解决easyui-datagrid在ie中无法reload问题
easyui在页面载入时,会自己主动填充datagrid中的数据,当加入.改动.删除后,会触发reload事件,对datagrid进行又一次载入. 这个过程在FireFox中没有问题,用firebug ...
- 如何在有实体键的情况下全部显示ActionBar的Menu?
大伙都知道, 在老版本手机, 以及部分的新手机上都还残留实体键, 有了这些实体键, 默认菜单是用实体菜单键呼出的, 尽管你把android:showAsAction="always" ...
- 关于php配置文件
一:配置文件(php.ini)在 PHP 启动时被读取.对于服务器模块版本的 PHP,仅在 web 服务器启动时读取一次.对于 CGI 和 CLI 版本,每次调用都会读取. 二:Note that t ...
- True Zero Downtime HAProxy Reloads--转载
原文地址:http://engineeringblog.yelp.com/2015/04/true-zero-downtime-haproxy-reloads.html HAProxy: Corner ...
- Kruskal算法 Swordfish
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=203 Swordfish Time Limit: 2 Seconds ...
- java6内置JS引擎初接触
本文系转载 原文地址:http://blog.csdn.net/sdyy321/article/details/6959199 由于要用到该技术,所以写了几个测试,直接上代码. 定义外部资源E:/Sc ...