通过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 ...
随机推荐
- MySQL 行溢出数据
MySQL 行溢出数据 MySQL 对一条记录占用的最大储存空间是有限制的,除了 BLOB 和 TEXT 类型之外,其他所有列 (不包括隐藏列和记录头信息) 占用的字节长度不能超过 65535 个字节 ...
- Linux 操作MySQL常用命令行
1.连接数据库 mysql -uroot -p Enter password: ** Mysql> 出现mysql>说明成功连接到数据 2.显示数据库 mysql> show dat ...
- CF1278C-Berry Jam-(前缀和)
https://vjudge.net/problem/CodeForces-1278C 题意:有2n瓶果酱,中间有一个楼梯隔开,从中间往左或右两边清空果酱,使得两种果酱的数量相等,最少要清空多少瓶 思 ...
- split task
和印度的team合作的时候,他们经常有些要求,然后我们这边有时候需要改代码来满足他们的需求. 最近一次,他们要求在我们的一个工具中为他们加入2个asp.net的注册命令,不知道什么原因,system ...
- 【2019.7.24 NOIP模拟赛 T1】道路建设(road)(水题)
原题与此题 原题是一道神仙不可做题,两者区别在于,原题不能有重边和自环. 然而,这题可以有重边... 于是这题就变成了一道大水题. 此题的解法 考虑如何构造. 对于\(n\le10^4\)的情况: 对 ...
- 深入理解Java8中Stream的实现原理
Stream Pipelines 前面我们已经学会如何使用Stream API,用起来真的很爽,但简洁的方法下面似乎隐藏着无尽的秘密,如此强大的API是如何实现的呢?比如Pipeline是怎么执行的, ...
- paramiko简介
一.什么是paramiko 要想明白什么是paramiko,要先明白ssh协议. 二.什么是ssh协议 ssh全称是Secure Shell (翻译:安全的外壳),根据字面意思就可以知道是和安全相关的 ...
- php imagemagick 翻译目录
图像处理(ImageMagick) 介绍 安装/配置 要求 安装 运行时配置 资源类型 预定义常数 例子 基本用法 Imagick - Imagick课 Imagick :: adaptiveBlur ...
- 如何自动生成 Entity Framework 的 Mapping 文件?
Program.cs using System; using System.IO; using System.Text; using System.Text.RegularExpressions; n ...
- FilterRegistrationBean注册过滤器探究
官方定义: A ServletContextInitializer to register Filters in a Servlet 3.0+ container. Similar to the re ...