网络编程之UDP
八、UDP
1.在Java中操纵UDP 使用位于JDK中Java.net包下的DatagramSocket和DatagramPacket类,可以非常方便地控制用户数据报文。
2.DatagramSocket类:创建接收和发送UDP的Socket实例
DatagramSocket():创建实例。通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。
DatagramSocket(int port):创建实例,并固定监听Port端口的报文。
DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文
receive(DatagramPacket d):接收数据报文到d中。receive方法产生一个“阻塞”。
send(DatagramPacket d):发送报文d到目的地。
setSoTimeout(int timeout):设置超时时间,单位为毫秒。
close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Sock
注意:1.在创建DatagramSocket类实例时,如果端口已经被使用,会产生一个SocketException的异常抛出,并导致程序非法终止,这个异常应该注意捕获。
3.“阻塞”是一个专业名词,它会产生一个内部循环,使程序暂停在这个地方,直到一个条件触发。
4.DatagramPacket:用于处理报文,将byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成byte数组。
DatagramPacket(byte[] buf, int length, InetAddress addr, int port):从buf数组中,取出length长的数据创建数据包对象,目标是addr地址,port端口。
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):从buf数组中,取出offset开始的、length长的数据创建数据包对象,目标是addr地址,port端口。
DatagramPacket(byte[] buf, int offset, int length):将数据包中从offset开始、length长的数据装进buf数组。
DatagramPacket(byte[] buf, int length):将数据包中length长的数据装进buf数组。
getData():它从实例中取得报文的byte数组编码。
(一)、发送消息
发短信。不用连接,但是需要对方的地址
发送端
package com.net;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
//不需要连接服务器
public class UdpClientDemo01 {
public static void main(String[] args) throws Exception {
//1.建立一个socket
DatagramSocket socket = new DatagramSocket();
//2.建个包
String msg = "Hello,服务器!";
//3.发送给谁
InetAddress localhost = InetAddress.getByName("localhost");
int port = 9090;
//数据,数据的长度起始,要发送给谁
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length,localhost,port);
//3.发送包
socket.send(packet);
//4.关闭流
socket.close();
}
}
接收端
package com.net;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//需要等待客户端的连接!!!
public class UdpServerDemo01 {
public static void main(String[] args) throws Exception {
//开放端口
DatagramSocket socket = new DatagramSocket(9090);
//接受数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet);//阻塞接受
System.out.println(packet.getAddress().getHostAddress());
System.out.println(new String(packet.getData(),0,packet.getLength()));
//关闭连接
socket.close();
}
}
(二)、循环发送消息
接收方
package com.chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpReceiveDemo01 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(6666);
while(true){
//准备接受包裹
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//阻塞时接收包裹
socket.receive(packet);
//断开连接bye
byte[] data = packet.getData();
String receiveData = new String(data, 0, data.length);
System.out.println(receiveData);
if(receiveData.equals("bye")){
break;
}
}
socket.close();
}
}
发送方
package com.chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class UdpSenderDemo01 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8888);
//准备数据:控制台读取System.in
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while(true){
String data = reader.readLine();
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas,0,datas.length, new InetSocketAddress("localhost",6666));
socket.send(packet);
if(data.equals("bye")){
break;
}
}
socket.close();
}
}
启动顺序,先接收,后发送方。检查成功:在发送方输入字符串,查看接收方的消息
(三)、相互咨询
结合了多线程
谈话发送端
package com.chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class TalkSend implements Runnable {
DatagramSocket socket = null;
BufferedReader reader = null;
private int fromPort;
private String toIP;
private int toPort;
public TalkSend(int fromIP, String toIP, int toPort) {
this.fromPort = fromIP;
this.toIP = toIP;
this.toPort = toPort;
try{
socket = new DatagramSocket(fromPort);
reader = new BufferedReader(new InputStreamReader(System.in));
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
try{
String data = reader.readLine();
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas,0,datas.length, new InetSocketAddress(this.toIP,this.toPort));
socket.send(packet);
if(data.equals("bye")){
break;
}
}catch (Exception e){
e.printStackTrace();
}
}
socket.close();
}
}
谈话接收端
package com.chat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class TalkReceive implements Runnable {
DatagramSocket socket = null;
private int port;//端口号
private String msfFrom;
public TalkReceive(int port, String msfFrom) {
this.port = port;
this.msfFrom = msfFrom;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
try {
//准备接受包裹
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//阻塞时接收包裹
socket.receive(packet);
//断开连接bye
byte[] data = packet.getData();
String receiveData = new String(data, 0, data.length);
System.out.println(msfFrom+":"+receiveData);
if(receiveData.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
学生端
package com.chat;
public class TalkSudent {
public static void main(String[] args) {
//开启两个线程
new Thread(new TalkSend(7777,"localhost",9999)).start();
new Thread(new TalkReceive(8888,"老师")).start();
}
}
老师端
package com.chat;
public class TalkTeaaher {
public static void main(String[] args) {
//两个进程,发送的端口 到达的端口
//接收时候的端口,从哪里来
new Thread(new TalkSend(5555,"localhost",8888)).start();
new Thread(new TalkReceive(9999,"学生")).start();
}
}
结果运行图
相关文章
- Java 网络编程的一些概念
- java基础——网络编程
- 网络编程 -- RPC实现原理 -- RPC -- 迭代版本V4 -- 远程方法调用 整合 Spring 自动注册
- 网络编程Netty IoT百万长连接优化
- 167 python网络编程 - Web静态服务器
- 166 python网络编程 - HTTP协议简介
- 162 python网络编程 - 协程
- 159 python网络编程 - 单进程服务器(非堵塞模式)
- 数学之美:图论和网络爬虫
- 《无线网络:理解和应对互联网环境下网络互连所带来的挑战》——2.2 IEEE
- 《面试八股文》之网络19卷
- Python爬虫技术--基础篇--网络编程
- 网络编程之TCP/UDP及其流程比较(转)
- Android网络编程概述
- 【漏洞通告】Windows 网络文件系统漏洞(CVE-2020-17051、CVE-2020-17056)
- Python网络编程(UDP客户端与服务器)
- 从零开始学android开发-通过WebService进行网络编程,使用工具类轻松实现
- Linux网络编程:基于UDP的程序开发回顾篇
- Python 网络编程之过多线程在两个单独的 GUI 之间进行通信(教程含完整源码)
- 【JavaSE】16-网络编程
- 《网络编程》ioctl 操作
- 完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三
- java网络编程
- Java网络编程——UDP聊天程序
- iOS开发之网络编程--4、NSURLSessionDataTask实现文件下载(离线断点续传下载) <进度值显示优化>
- 学习笔记(29):Python网络编程&并发编程-信号量
- 学习笔记(26):Python网络编程&并发编程-GIL与自定义互斥锁的区别
- C#网络编程TCP通信实例程序简单设计