iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java网络编程之UDP实现原理解析
  • 913
分享到

Java网络编程之UDP实现原理解析

2024-04-02 19:04:59 913人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

UDP实现通信非常简单,没有服务器,每个都是客户端,每个客户端都需要一个发送端口和一个接收端口。一个客户端向另一个客户端发送消息时,需要知道对方的IP和接收端口,所用到的类为Data

UDP实现通信非常简单,没有服务器,每个都是客户端,每个客户端都需要一个发送端口和一个接收端口。一个客户端向另一个客户端发送消息时,需要知道对方的IP和接收端口,所用到的类为DatagramSocket

DatagramSocket socket =new DatagramSocket(),发送端socket,若不指定端口,系统自动分配

DatagramSocket socket =new DatagramSocket("接收信息端口"),接收端socket,需要指定接收端口

​ 若想客户端之间进行全双工通信,每个客户端都要有两个线程,一个用于发送信息,一个用于接收信息。

​ 那么UDP怎么实现私聊和群聊呢?(在本机一台电脑的情况下实现)

​ 首先私聊,客户端向另一个客户端发送消息,就要知道其IP(本机都是固定的localhost)和接收端口,也需要姓名进行标识,所以,每个客户端都至少要自己的姓名和接收端口,而且端口不可重复,否则会报端口被占用的错。

​ 其次群聊,由于在本机一台电脑上进行,接收端口各不相同,所以广播就不行了,此时就希望每个客户端在启动的时候,能够把自己的姓名和接收端口给存起来,然后就可以遍历进行群聊。

​ 实现:

  • 第一种,在每个客户端启动时,输入自己的姓名和接收端口,发送信息时,需要输入对方的接收端口号,如果输入时输入了多个端口,就是群发。那么这样每次发送信息时都要指定对方的端口。。。
  • 第二种,客户端启动时,输入姓名和接收端口,此时就把数据存起来,发送信息时,只用指定对方姓名即可。。。可用数据库存,可用文件存,我用的是XML来存。

要创建xml文件,路径在Operation类中

UdpClient.java:


public class UdpClient {

	public static void main(String[] args) {
		try {
			Scanner scanner = new Scanner(System.in);
			User user = new User();
			System.out.print("请输入用户名》》");
			String userName = scanner.next();
			if (Operation.userIsExist(userName)) {
				//如果此用户已经注册过,直接把注册时用的接收端口分配给他
				user = Operation.findUserByName(userName);
			}else {
				//未注册,用户自己指定端口
				while(true) {
					System.out.println("请输入接收端口》》");
					int port = Integer.parseInt(scanner.next());
					if (Operation.portIsExist(port)) {
						System.err.println("该端口已被使用,请重新输入。。。。");
						continue;
					}else {
						user.setName(userName);
						user.setPort(port);
						Operation.addUser(user);
						break;
					}
				}
			}
			new Thread(new SendMsg(user)).start();
			new Thread(new ReceiveMsg(user)).start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

发送信息:


public class SendMsg implements Runnable{

	private User self = null;
	private DatagramSocket socket = null;
	private BufferedReader reader = null;
	public SendMsg(User self) {
		try {
			socket = new DatagramSocket();
			reader = new BufferedReader(new InputStreamReader(System.in));
			this.self = self;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Override
	public void run() {	
		try {
			while(true) {
				String[] msg = reader.readLine().split("@");
				if (msg.length != 2) {
					System.err.println("注意格式:消息@对方名字(私聊)或all(群聊)");
					continue;
				}
				msg[0] = self.getName()+"说:"+msg[0];
				byte[] data = msg[0].getBytes();
				String toPerson = msg[1];
				if (("all").equals(toPerson)) {
					//群聊,获取所有用户,不管对方在不在线,都发过去
					List<User> users = Operation.getUsers();
					for(User user:users) {
						if (self != user) {
							DatagramPacket packet = new DatagramPacket(data, 0,data.length,new InetSocketAddress("localhost",user.getPort()));
						    socket.send(packet);
						}
					}
				}else {
					//私聊
					try {
						DatagramPacket packet = new DatagramPacket(data, 0,data.length,new InetSocketAddress("localhost",Operation.findUserByName(toPerson).getPort()));
				        socket.send(packet);
					} catch (Exception e) {
						System.out.println("对方不在线。。。");
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

接收消息:


public class ReceiveMsg implements Runnable{

	private DatagramSocket socket = null;
	public ReceiveMsg(User user) {
		try {
			socket = new DatagramSocket(user.getPort());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Override
	public void run() {
		try {
			while(true) {
				//准备接收包裹
				byte[] container = new byte[1024];
				DatagramPacket packet = new DatagramPacket(container,0,container.length);
				socket.receive(packet);
				byte[]data = packet.getData();
				String receiveData = new String(data, 0, data.length);
				System.out.println(receiveData);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		socket.close();
	}
}

操作XML文件类:


public class Operation {
	private static String FILE_PATH = "config/user.xml";     //文件目录
 
        //在xml文件中添加一个用户信息
	public static void addUser(User user)
	{
		InputStream in = null;
		SAXReader reader = new SAXReader();
		Document doc = null;
		try
		{
			in = new FileInputStream(FILE_PATH);
			doc = reader.read(in);
			Element root = doc.getRootElement();   //获取xml根节点,即users节点
			Element element = root.addElement("user");
			element.addElement("name").addText(user.getName());
			element.addElement("port").addText(String.valueOf(user.getPort()));
 
			FileOutputStream fos = new FileOutputStream(FILE_PATH);
			//格式化xml文件
			OutputFORMat format = OutputFormat.createPrettyPrint();
			format.setEncoding("utf-8");
			XMLWriter writer = new XMLWriter(fos,format);
			writer.write(doc);
			writer.close();
		}
		catch (Exception e)
		{
			System.out.println("error");
		}
		finally
		{
			try
			{
			
				if(in != null)
					in.close();
			}
			catch (IOException e)
			{
				System.out.println("error");
			}
		}
	}
 
        //列出xml中所有用户信息
	public static List<User> getUsers()
	{
		InputStream in = null;
		SAXReader reader = new SAXReader();
		Document doc = null;
		List<User> users = new ArrayList<>();
		try
		{
			in = new FileInputStream(FILE_PATH);
			doc = reader.read(in);
			Element root = doc.getRootElement();
			List<Element> elements = root.elements();
			for (Element element : elements)
			{
				User user = new User();
				user.setName(element.elementText("name"));
				user.setPort(Integer.valueOf(element.elementText("port")));
				users.add(user);
			}
		}
		catch (Exception e1)
		{
			System.out.println("error");
		}
		finally
		{
			try
			{
				in.close();
			}
			catch (IOException e)
			{
				System.out.println("error");
			}
		}
 
		return users;
	}
	public static User findUserByName(String name) {
		InputStream in = null;
		SAXReader reader = new SAXReader();
		Document doc = null;
		try {
			in = new FileInputStream(FILE_PATH);
			doc = reader.read(in);
			Element root = doc.getRootElement();
			List<Element> elements = root.elements();
			for (Element element : elements)
			{
				if(name != null && name.equals(element.elementText("name"))) {
					User user = new User();
					user.setName(name);
					user.setPort(Integer.parseInt(element.elementText("port")));
					return user;
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static boolean portIsExist(int port) {
		InputStream in = null;
		SAXReader reader = new SAXReader();
		Document doc = null;
		
		try {
			in = new FileInputStream(FILE_PATH);
			doc = reader.read(in);
			Element root = doc.getRootElement();
			List<Element> elements = root.elements();
			for (Element element : elements)
			{
				if(port == Integer.parseInt(element.elementText("port")))
					return true;
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return false;
	}
        //判断某个用户是否存在该xml中
	public static boolean userIsExist(String name) 
	{
		InputStream in = null;
		SAXReader reader = new SAXReader();
		Document doc = null;
		try {
			in = new FileInputStream(FILE_PATH);
			doc = reader.read(in);
			Element root = doc.getRootElement();
			List<Element> elements = root.elements();
			for (Element element : elements)
			{
				if(name != null && name.equals(element.elementText("name")))
					return true;
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return false;
	}
}

用户实体类:


public class User implements Serializable{

	private String name;//姓名
	private int port;//接收端口
	public String getName() {
		return name;
	}
	public int getPort() {
		return port;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setPort(int port) {
		this.port = port;
	}
	@Override
	public String toString() {
		return "User [name=" + name + ", port=" + port + "]";
	}
	
}

运行结果:

到此这篇关于Java网络编程之UDP实现原理解析的文章就介绍到这了,更多相关Java网络编程UDP内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java网络编程之UDP实现原理解析

本文链接: https://www.lsjlt.com/news/134630.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java网络编程之UDP实现原理解析
    UDP实现通信非常简单,没有服务器,每个都是客户端,每个客户端都需要一个发送端口和一个接收端口。一个客户端向另一个客户端发送消息时,需要知道对方的IP和接收端口,所用到的类为Data...
    99+
    2022-11-12
  • Java网络编程之UDP网络通信详解
    目录1.UDP网络通信编程原理1.1 UDP网络通信编程介绍1.2 UDP网络通信编程的基本流程2.UDP网络通信编程案例1.UDP网络通信编程原理 1.1 UDP网络通信编程介绍 ...
    99+
    2022-11-13
  • Java网络编程之UDP和TCP套接字
    文章目录 一. 网络编程概述二. UDP网络编程1. UDP套接字2. UDP客户端回显服务器程序2.1 UDP回显服务器2.2 UDP客户端2.3 UDP实现查词典的服务器 三. ...
    99+
    2023-09-08
    网络编程 Java Socket UDP/TCP 套接字
  • Java实现基于UDP协议的网络通信UDP编程
    目录UDP编程通信基本介绍基本流程UDP编程通信 基本介绍 类DatagramSocket和DatagramPacket【数据包/数据报】实现了基于UDP协议网络程序。UDP数据报通...
    99+
    2023-05-17
    Java UDP编程 Java UDP网络编程
  • Java网络编程UDP实现多线程在线聊天
    本文实例为大家分享了Java实现多线程在线聊天的具体代码,供大家参考,具体内容如下 上一篇博客通过UDP实现了聊天,但只能单方面发送消息,这次实现了多线程在线聊天,也就是可以双方互发...
    99+
    2022-11-12
  • Android网络编程之UDP通信模型实例
    什么是Android UDP? UDP是User Datagram Protocol的简称,中文名是用户数据包协议,是OSI参考模型中一种无连接的传输层协议,提供面向事务的简单...
    99+
    2022-06-06
    模型 udp Android
  • C++ Socket实现TCP与UDP网络编程
    目录前言TCP1). 服务器2). 客户端3). TCP聊天小项目UDP1). 服务器2). 客户端总结前言 socket编程分为TCP和UDP两个模块,其中TCP是可靠的、安全的,...
    99+
    2022-11-13
  • Java网络编程UDP实现消息发送及聊天
    TCP可以实现聊天,UDP也可以实现消息发送及聊天。不同的是,TCP需要有服务端和客户端的连接,但UDP不需要,只需要有发送方和接收方即可。 一、实现消息发送 发送方: pack...
    99+
    2022-11-12
  • 如何解析C# Socket编程实现访问网络的原理
    这期内容当中小编将会给大家带来有关如何解析C# Socket编程实现访问网络的原理,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在C# Socket编程学习中,我们知道MS为我们提供了System.Net...
    99+
    2023-06-17
  • Java之网络编程的示例分析
    小编给大家分享一下Java之网络编程的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java基础之网络编程基本概念IP:每个电脑都有一个IP地址,在局域网...
    99+
    2023-06-20
  • Java之网络编程案例讲解
    Java基础之网络编程 基本概念 IP:每个电脑都有一个IP地址,在局域网内IP地址是可变的。 网络通信协议:通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进行通...
    99+
    2022-11-12
  • Java并发编程之ReentrantLock实现原理及源码剖析
    目录一、ReentrantLock简介二、ReentrantLock使用三、ReentrantLock源码分析1、非公平锁源码分析2、公平锁源码分析前面《Java并发编程之JUC并发...
    99+
    2022-11-12
  • 【Linux网络】网络编程套接字 -- 基于socket实现一个简单UDP网络程序
    认识端口号网络字节序处理字节序函数 htonl、htons、ntohl、ntohs socketsocket编程接口sockaddr结构结尾实现UDP程序的socket接口使用解析so...
    99+
    2023-09-01
    网络 linux udp socket
  • Java网络编程之简易聊天室的实现
    目录一、题目描述二、解题思路三、代码详解一、题目描述 题目实现:运行客户端,连接服务器。 二、解题思路 首先需要启动上题的ServerSocketFrame服务,这样客户端运行时,才...
    99+
    2022-11-13
    Java实现简易聊天室 Java 聊天室
  • Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理
    本文转自互联网本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看https://github.com/h3pl/Java-Tutorial喜欢的话麻烦点下Star哈文章将同步到我的个人博客:www...
    99+
    2023-06-02
  • 图文分析详解计算机网络TCP与UDP两者区别及原理
    目录1、概念2、从是否面向连接来看2.1、UDP2.2、TCP3、从连接对象个数来看3.1、UDP3.2、TCP4、从对应用报文的处理来看4.1、UDP4.2、TCP发送方:接收方:...
    99+
    2022-11-12
  • Java Spring AOP源码解析之事务实现原理
    目录不用Spring管理事务?编程式事务管理使用PlatformTransactionManager使用TransactionTemplate声明式事务管理使用@Transactio...
    99+
    2022-11-12
  • Java IO网络模型实现解析
    目录前言正文一. BIO二. Non Blocking IO三. IO多路复用四. NIO总结前言 本篇文章会对Java中的网络IO模型的概念进行解释,并给出具体的Java代码实现...
    99+
    2023-03-19
    Java IO网络模型 Java IO
  • C++基于socket UDP网络编程实现简单聊天室功能
    本文实例为大家分享了C++基于socket UDP实现简单聊天室功能的具体代码,供大家参考,具体内容如下 0.通信步骤流程图 (左:服务器;右:客户端;) 1.服务器代码 1.1服...
    99+
    2022-11-12
  • C++基于socket UDP网络编程如何实现聊天室功能
    这篇文章主要介绍C++基于socket UDP网络编程如何实现聊天室功能,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体内容如下0.通信步骤流程图(左:服务器;右:客户端;)1.服务器代码1.1服务器类头文件(CS...
    99+
    2023-06-20
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作