网络编程——UDP编程

网络编程——UDP编程一、网络编程基础1.常用协议:IP协议;TCP协议;UDP协议;2.什么是Socket?二、服务器端的代码实现三、客户端的代码实现1.区别2.易混淆知识点四.代码实现五.最后小结

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、网络编程基础

        计算机网络是指两台或更多的计算机组成的网络,在同一个网络中,任意两台计算机都可以直接通信,因为所有计算机都需要遵循同一种网络协议。因此,为了把计算机网络接入互联网,就必须使用TCP/IP协议。

1.常用协议

IP协议只负责发数据包,不保证顺序和正确性,而TCP协议负责控制数据包传输,它在传输数据之前需要先建立连接,建立连接后才能传输数据,传输完后还需要断开连接。

UDP协议(User Datagram Protocol)是一种数据报文协议,它是无连接协议不保证可靠传输。因为UDP协议在通信前不需要建立连接,因此它的传输效率比TCP高,而且UDP协议比TCP协议要简单得多。选择UDP协议时,传输的数据通常是能容忍丢失的,例如,一些语音视频通信的应用会选择UDP协议。

2.什么是Socket?

         Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据传输到网络。可以把Socket简单理解为IP地址加端口号。端口号总是由操作系统分配,它是一个0~65535之间的数字,其中,小于1024的端口属于特权端口,需要管理员权限,大于1024的端口可以由任意用户的应用程序打开。

       因此,当Socket连接成功地在服务器端和客户端之间建立后:对服务器端来说,它的Socket是指定的IP地址和指定的端口号;对客户端来说,它的Socket是它所在计算机的IP地址和一个由操作系统分配的随机端口号。

UDP端口和TCP端口虽然都使用0~65535,但他们是两套独立的端口,即一个应用程序用TCP占用了端口1234,不影响另一个应用程序用UDP占用端口1234 

二、服务器端 

要使用Socket编程,我们首先要编写服务器端程序。Java标准库提供了ServerSocket来实现对指定IP和指定端口的监听。ServerSocket的典型实现代码如下:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.HashMap;
import java.util.Map;

public class WorkDisctServer {
	public static void main(String[] args) {
		
		Map<String, String> wordMap = new HashMap<String, String>(){
			{
				put("one", "壹");
				put("two", "贰");
				put("three", "叁");
				put("four", "肆");
				put("five", "伍");
				put("six", "陆");
				put("serven", "柒");
			}
		};
	
		try (DatagramSocket serverSocket = new DatagramSocket(7788)) {
			while(true) {
				// 准备"空"数据包
				byte[] buff = new byte[1024];// 原始的字节数组
				DatagramPacket packet = new DatagramPacket(buff, buff.length);
				
				// 读取(客户端发送的英文单词)
				// 接收数据包
				serverSocket.receive(packet);
				
				// 获取数据包中的"数据"(字节数组) 
				// 获取数据包中的“读取位置”(int类型)
				// 获取数据包中的“长度”
				String word = new String(
						packet.getData(),
						packet.getOffset(),
						packet.getLength());
				System.out.println("【服务器】:获取来自客服端的单词"+word);
				
				String chinese = wordMap.get(word);
				if(chinese == null) {
					chinese = "未知结果";
				}
				
				//发送(向客户端发送中文释义)
				byte[] resultbuff = chinese.getBytes();
				packet.setData(resultbuff);
				serverSocket.send(packet);
			
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	
	}

}

三、客户端

和服务器端相比,客户端使用UDP时,只需要直接向服务器端发送UDP包,然后接收返回的UDP包: 

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Scanner;

public class WorkDictClient {
	public static void main(String[] args) {

		Scanner input = new Scanner(System.in);

		while (true) {
			String word = input.nextLine();
			if (word.equals("end")) {
				break;
			}

			// 创建基于UDP协议的DatagramSocket对象
			try (DatagramSocket clientSocket = new DatagramSocket()) {
				// timeout超时
				clientSocket.setSoTimeout(2000);

				// 连接服务器(服务器IP和端口)
				clientSocket.connect(new InetSocketAddress("192.168.254.178", 7788));

				// 发送(向服务发送一个英文单词)
				// String word = "one";
				byte[] wordbuff = word.getBytes();// 获取英文单词字符串的字节数组

				// 封装成DatagramPacket对象(数据包)
				DatagramPacket packet = new DatagramPacket(wordbuff, wordbuff.length);

				// 发送数据包
				clientSocket.send(packet);

				// 读取
				byte[] resultbuff = new byte[1024];
				DatagramPacket resultPacket = new DatagramPacket(resultbuff, resultbuff.length);
				clientSocket.receive(resultPacket);

				String result = new String(resultPacket.getData(), resultPacket.getOffset(), resultPacket.getLength());
				System.out.println("来自服务器的中文释义" + result);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

区别

1.客户端创建DatagramSocket实例时并不需要指定端口,而是由操作系统自动指定一个当前未使用的端口。紧接着,调用setSoTimeout(1000)设定超时1秒,意思是后续接收UDP包时,等待时间最多不会超过1秒,否则在没有收到UDP包时,客户端会无限等待下去。这一点和服务器端不一样,服务器端可以无限等待,因为它本来就被设计成长时间运行。

2.如果客户端希望向两个不同的服务器发送UDP包,那么它必须创建两个DatagramSocket实例。后续的收发数据和服务器端是一致的。通常来说,客户端必须先发UDP包,因为客户端不发UDP包,服务器端就根本不知道客户端的地址和端口号。

易混淆知识点:

1.注意到客户端的DatagramSocket还调用了一个connect()方法“连接”到指定的服务器端。不是说UDP是无连接的协议吗?为啥这里需要connect()?

       这个connect()方法不是真连接,它是为了在客户端的DatagramSocket实例中保存服务器端的IP和端口号,确保这个DatagramSocket实例只能往指定的地址和端口发送UDP包,不能往其他地址和端口发送。这么做不是UDP的限制,而是Java内置了安全检查。

2.如果客户端认为通信结束,就可以调用disconnect()断开连接。

       disconnect()也不是真正地断开连接,它只是清除了客户端DatagramSocket实例记录的远程服务器地址和端口号.这样,DatagramSocket实例就可以连接另一个服务器端。

四、实现结果:

网络编程——UDP编程


知识小结:

  • 使用UDP协议通信时,服务器和客户端双方无需建立连接;
  • 服务器端用DatagramSocket(port)监听端口;
  • 客户端使用DatagramSocket.connect()指定远程地址和端口;
  • 双方通过receive()和send()读写数据;
  • DatagramSocket没有IO流接口,数据被直接写入byte[]缓冲区;

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/195885.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • ipad 运行linux_linux 终端快捷键

    ipad 运行linux_linux 终端快捷键实现的具体步骤如下:1.、cydia安装openssh2、installous安装issh3、进入issh,选addconfigurationdescription:随便填host:localhostport:22login:rootpassword:默认为alpine(这个进入以后可以改)保存,连接4、连接时会出现一个警告,点确认即可于是出现:***-mato-ipad:-root#现在就可…

  • CSDN博客导出工具 Mac By Swift

    CSDN博客导出工具 Mac By Swift

  • jmeter正则提取器用法_jmeter字符串截取

    jmeter正则提取器用法_jmeter字符串截取JMeter正则表达式提取器 转自:http://desert3.iteye.com/blog/1394934//提取HTML中隐藏域的值^(.*)$ //提取整个response返回提取MyLabel关联的input的值MyLabel”(.+:create:.+?)”  //提取下面link的href的值JSESSIONI

  • JSONObject和JSONArray的转换[通俗易懂]

    JSONObject和JSONArray的转换[通俗易懂]转换的时候原本写的是 两个类都写的是:JSONArray jsonArray =(JSONArray)jsonObject.get(“List”);结果一个转换没错,另一个后台报错java.util.ArrayListcannotbecasetocom.alibaba.fastjson.JSONArray 转换成JSONArrayjsonArr

  • java开发简历项目经验_java工程师简历案例

    java开发简历项目经验_java工程师简历案例 最近我在帮朋友的公司招人,招人的第一步是要筛选简历,在这过程中,我发现虽然能收到很多简历,但实际能通过筛选能进入到技术面试流程的简历不多,估计10份里不会超过4份能通过筛选。  如果没法通过技术面试,那么候选人尚且能收集面试题,回家继续准备,毕竟他和面试官也交流过,也不算没收获,但对于这些没法通过筛选的简历,简历的主人往往是无从得知的(公司不会主动通知),所以他们依然会混混沌沌,可以预想,在…

  • Android退出应用程序方法总结[通俗易懂]

    Android退出应用程序方法总结[通俗易懂]Android退出应用程序方法总结在Android开发中,我们运行了应用程序后,都需要退出应用的,那么该如何退出应用,又都有哪些实现方式呢?今天就为大家整理分享一些退出应用程序的方法,一起来看看吧!更新内容Ver:v1任务管理器方法补充 新增监听式退出方法Ver:v2任务管理器方法修正 新增销毁任务栈退出方法1.finish方法finish();该方法只是结束当前Activity,系统将最上面的Activity移出了栈,并没有清理占用的资源。如果栈内有很多Activ

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号