网络编程——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)


相关推荐

  • openGL ES美颜滤镜之美白,磨皮,红润[通俗易懂]

    openGL ES美颜滤镜之美白,磨皮,红润[通俗易懂]下面是滤镜源码:importandroid.app.Activity;importandroid.content.Context;importandroid.graphics.Bitmap;importandroid.opengl.GLES20;importandroid.opengl.GLSurfaceView;importandroid.opengl.Matrix;importandroid.view.WindowManager;importcom.ws.gl.o

  • 计算机的通信协议_计算机通信网络层级

    计算机的通信协议_计算机通信网络层级系列文章目录提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加例如:第一章Python机器学习入门之pandas的使用提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录系列文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结前言提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的

  • Symfony2 细节小计4

    Symfony2 细节小计4

  • Springboot整合SSM

    Springboot整合SSM1.1创建SSM模块1.1.1系统架构图1.1.2项目结构1.1.3需求访问:http://localhost:8080/car/get返回:{“name”:”BMW”,”color”:”red”,”price”:9.9}1.1.4准备表,数据CREATETABLE`car`(`id`int(11)NOTNULLauto_increment,`name`varchar(10)defaultNULL,`color`varchar(10)d

  • pthreads php 安装全过程(二)

    pthreads php 安装全过程(二)

  • 用python的pandas打开csv文件_如何使用Pandas DataFrame打开CSV文件 – python[通俗易懂]

    用python的pandas打开csv文件_如何使用Pandas DataFrame打开CSV文件 – python[通俗易懂]有一个带有三列数据框的CSV格式文件。第三栏文字较长。当我尝试使用pandas.read_csv打开文件时,出现此错误消息message:UnicodeDecodeError:’utf-8’codeccan’tdecodebyte0xa1inposition0:invalidstartbyte.但是用打开文件没有问题withopen(‘file.csv’,’r’,…

发表回复

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

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