通过DatagramSocket实现UDP编程(十三)
原文链接:https://www.cnblogs.com/hysum/p/7533149.html
UDP通信:
- UDP协议(用户数据报协议)是无连接、不可靠、无序的。
- UDP协议以数据报作为数据传输的载体。
- 使用UDP进行数据传输时,首先需要将要传输的数据定义成数据报(Datagram),在数据报中指明所要达到的Socket(主机地址和端口号),然后在将数据报发生出去。
相关操作类:
- DatagramPacket:表示数据报包
- DatagramSocket:进行端到端通信的类
一、DatagramPacket&DatagramSocket类的常用方法
1. DatagramPacket类
- DatagramPacket(byte[] buf,int length)//接受长度为length的数据包
- DatagramPacket(byte[] buf,int length,InetAddress address,int port)//将指定长度的字节发生到指定主机的指定端口
2. DatagramSocket类
构造方法:
- DatagramSocket();
- DatagramSocket(int port,InetAddress laddr);
常用方法:
- close();//关闭DatagramSocket
- getInetAddress();//获取地址
- getPort();//获取端口号
- send(DatagramPacket p);//从此套接字发送数据包
- recrive(DatagramPacket p);//从此套接字接收数据包
二、编程实现基于UDP的用户登录小程序
1. 服务端
- 创建DatagramSocket,指定端口号
- 创建DatagramPacket
- 接收客户端发送的数据信息
- 读取数据
public class UdpServer {
public static void main(String[] args) throws IOException {
try {
/*
* 接收客户端发送的数据
*/
//1.创建服务器端DatagramSocket,指定端口
DatagramSocket ds=new DatagramSocket(8080);
//2.创建数据报DatagramPacket,用于接收客户端发送的数据
byte[] data=new byte[1024];//创建字节数组,指定接受的数据报大小
DatagramPacket dp=new DatagramPacket(data, data.length);
//3.接收客户端发送的数据
System.out.println("服务器端已启动,等待客户端发送数据...");
ds.receive(dp);//此方法在接收到数据报之前会一直阻塞
//4.读取数据
//String info=Arrays.toString(data);
String info=new String(data, 0, dp.getLength());
System.out.println("我是服务器,客户端说:"+info);
/*
* 响应客户端
*/
//1.定义客户端的地址、端口号、数据
InetAddress add=dp.getAddress();
int port=dp.getPort();
byte[] data2="欢迎您!".getBytes();
//2.创建数据报,包含响应的数据信息
DatagramPacket dp2=new DatagramPacket(data2, data2.length, add, port);
//3.响应客户端
ds.send(dp2);
//4.关闭资源
ds.close(); } catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2. 客户端
- 定义发送信息
- 创建DatagramPacket:包含将要发送信息
- 创建DatagramSocket
- 发送数据
public class UdpClient {
public static void main(String[] args) throws IOException {
/*
* 向服务器发送数据
*/
//1.定义服务器的地址、端口号、数据
InetAddress add=InetAddress.getByName("localhost");
int port=8080;
byte[] data="用户名:admin;密码:123".getBytes();
//2.创建数据报,包含了发送的相关信息
DatagramPacket ap=new DatagramPacket(data, data.length, add, port);
//3.创建DatagramSocket对象
DatagramSocket ds=new DatagramSocket();
//4.向服务器端发送数据报
ds.send(ap);
/*
* 接收服务器端的响应
*/
//1.创建数据报DatagramPacket,用于接收服务器发送的数据
byte[] data2=new byte[1024];
DatagramPacket dp2= new DatagramPacket(data2, data2.length);
//2.接收响应
ds.receive(dp2);
//3.读取数据
String info=new String(data2, 0, dp2.getLength());
System.out.println("我是客户端,服务器说:"+info);
//4.关闭资源
ds.close();
} }
三、使用多线程实现多客户端的通信
多线程基本步骤:
- 服务器端创建DatagramSocket,循环调用receive()等待客户端发送数据报。
- 客户端创建一个DatagramSocket发送数据报到服务器端。
- 服务器端接收客户端的数据报,创建DatagramPacket与该客户建立专线接收数据报。
- 建立交互数据报在一个单独的线程上对话。
- 服务器端继续等待新的数据报。
新建一个服务器线程处理类UDPServerThread,该类继承Thread类:
/*
* 服务器线程处理类
*/
public class UDPServerThread extends Thread {
DatagramSocket ds = null;
DatagramPacket dp = null; public UDPServerThread(DatagramSocket ds, DatagramPacket dp) {
this.ds = ds;
this.dp = dp;
} public void run() {
try {
/*
* 接收客户端发送的数据
*/ // 4.读取数据
// String info=Arrays.toString(data);
byte[] data = dp.getData();
String info = new String(data, 0, dp.getLength());
System.out.println("我是服务器,客户端说:" + info);
/*
* 响应客户端
*/
// 1.定义客户端的地址、端口号、数据
InetAddress add = dp.getAddress();
int port = dp.getPort();
byte[] data2 = "欢迎您!".getBytes();
// 2.创建数据报,包含响应的数据信息
DatagramPacket dp2 = new DatagramPacket(data2, data2.length, add, port);
// 3.响应客户端
ds.send(dp2); } catch (IOException e) {
e.printStackTrace();
} }
}
服务端:
/*
* 服务器端
*/
public class UDPSever { public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub try { // 1.创建服务器端DatagramSocket,指定端口
DatagramSocket ds = new DatagramSocket(8080);
System.out.println("服务器即将启动,等待客户端的连接...");
byte[] data = new byte[1024];
// 记录客户端的数量
int count = 0;
// 循环侦听等待客户端的连接
while (true) {
DatagramPacket dp = new DatagramPacket(data, data.length);
ds.receive(dp);
// 创建一个新的线程
UDPServerThread udp = new UDPServerThread(ds, dp);
// 启动线程,执行与客户端的交互
udp.start();
count++;
System.out.println("此时客户端数量为:" + count);
InetAddress add = dp.getAddress();
System.out.println("当前客户端的ip地址为" + add.getHostAddress());
} } catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
通过DatagramSocket实现UDP编程(十三)的更多相关文章
- 【Socket编程】通过Socket实现UDP编程
通过Socket实现UDP编程 UDP通信: 1.UDP协议(用户数据报协议)是无连接.不可靠.无序的. 2.UDP协议以数据报作为数据传输的载体. 3.使用UDP进行数据传输时,首先需要将要传输的数 ...
- 网络编程之UDP编程
网络编程之UDP编程 UDP协议是一种不可靠的网络协议,它在通信的2端各建立一个Socket,但是这个Socket之间并没有虚拟链路,这2个Socket只是发送和接受数据的对象,Java提供了Data ...
- 牛客网Java刷题知识点之TCP、UDP、TCP和UDP的区别、socket、TCP编程的客户端一般步骤、TCP编程的服务器端一般步骤、UDP编程的客户端一般步骤、UDP编程的服务器端一般步骤
福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号: 大数据躺过的坑 Java从入门到架构师 人工智能躺过的坑 Java全栈大联盟 ...
- 62 网络编程(三)——UDP编程
UDP编程标准步骤 服务器端 使用DatagramSocket创建服务端:DatagramSocket server = new DatagramSocket(port);//参数为自定义端口号 准备 ...
- Linux学习四:UDP编程(上)
关于UDP和TCP对比优缺,这里就不说了. 使用UDP代码所掉用的函数和用于TCP的函数非常类似,这主要因为套接口库在底层的TCP和UDP的函数上加了一层抽象,通过这层抽象使得编程更容易,但失去了一些 ...
- DatagramSocket收发UDP数据包
Java的Socket通信分为TCP和UDP两种,Socket和ServerSocket类用于TCP通信,DatagramSocket用于UDP通信. 使用DatagramSocket发送UDP数据包 ...
- [C# 网络编程系列]专题七:UDP编程补充——UDP广播程序的实现
转自:http://www.cnblogs.com/zhili/archive/2012/09/03/2666974.html 上次因为时间的关系,所以把上一个专题遗留下的一个问题在本专题中和大家分享 ...
- [C# 网络编程系列]专题六:UDP编程
转自:http://www.cnblogs.com/zhili/archive/2012/09/01/2659167.html 引用: 前一个专题简单介绍了TCP编程的一些知识,UDP与TCP地位相当 ...
- Socket编程实践(12) --UDP编程基础
UDP特点 无连接,面向数据报(基于消息,不会粘包)的传输数据服务; 不可靠(可能会丢包, 乱序, 反复), 但因此普通情况下UDP更加高效; UDP客户/服务器模型 UDP-API使用 #inclu ...
随机推荐
- 小米笔记本pro 黑苹果系统无法进入系统,频繁重启故障解决记录
问题1:频繁重启,然后clover丢失 表现情况:开机没有选择macos 或windos的界面 解决办法:进入windows使用工具easyefi,直接添加一个clover start boot,选择 ...
- JavaScript DOM 常用操作
1.理解DOM: DOM(Document Object Model ,文档对象模型)一种独立于语言,用于操作xml,html文档的应用编程接口. 怎么说,我从两个角度理解: 对于JavaScript ...
- 最锋利的Visual Studio Web开发工具扩展:Web Essentials详解【转】
Web Essentials是目前为止见过的最好用的VS扩展工具了,具体功能请待我一一道来. 首先,从Extension Manager里安装:最新版本是19号发布的2.5版 然后重启你的VS开发环境 ...
- Python3.0的新特性
网上关于Python3与Python2的区别的文章都烂大街了,但基本上都是抄来抄去,为了追本溯源,直接看官网最靠谱,官网文档的结构性更强. 本文是对Python3.0官网文档 What's New I ...
- Linux(CentOS)启动时自动执行脚本(rc.local)
下面说说通过rc.local文件进行开机启动 1.首先创建一个启动脚本,这里以启动docker为例 创建 docker-startup.sh 脚本 #! /bin/bash /usr/bin/mk-d ...
- Zabbix server 更改数据库密码
Zabbix server 更改数据库密码 当我们的 Zabbix server 使用的数据库信息发生了改变,我们需要更改旧配置. 涉及到数据库配置信息的文件有2个,分别是 /etc/zabbix/z ...
- C# 学习笔记 多态(二)抽象类
多态是类的三大特性之一,抽象类又是多态的实现方法之一.抽象类是什么呢,如果把虚方法比作一个盛有纯净水的杯子,那么此时的“纯净水”就是事先定义好的方法,我们可以根据不同的需求来改变杯子中所事先盛放的是“ ...
- Python - Socket网络编程 - 第二十六天
网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法. 高 ...
- 开发技术--Python核心知识A
开发|Python核心知识A A篇,主要介绍Python基础中列表,元祖,字典,集合,字符串,I/O,条件与循环,异常处理的底层知识与使用的注意事项. 希望大家对于Python会有新的收获,本篇不同于 ...
- springmvc在使用@ModelAttribute注解获取Request和Response会产生线程并发不安全问题(转)
springmvc在获取Request和Response有很多方式:具体请看:https://www.cnblogs.com/wade-luffy/p/8867144.html 产生线程问题的代码如下 ...