udp/tcp回显网络编程

udp
DatagramSocket 

用于接收和发送udp数据报


构造方法:

  • DatagramSocket():创建一个UDP数据报套接字的Socket,绑定到本地上 一个随机可用端口上,一般用于客户端
  • DatagramSocket(int port):创建一个UDP数据报套接字的Socket,绑定到指定端口上,一般适用于服务器端

DatagramSocket方法:

  • void receive(DatagramPacket p):接收套接字数据报p,如果此时还没有发送,便会阻塞
  • void send(DatagramPacket p):发送套接字数据报p,不会阻塞,直接发送
  • void close():关闭此数据报套接字
DatagramPacket:

udp发送和接收的数据报形式


构造方法:

  • DatagramPacket(byte[] buf,int length):构造一个DatagramPacket对象来接收发送来到数据报,将数据内容放在第一个字节数组中,第二个参数是指定接收内容的长度。(用于接收时)
  • DatagramPacket(byte[] buf,int offset,int length,SocketAddress address):接收发来的数据报,并将内容放进buf数组中,选中需要截取内容的索引[offset,length)。address:指定目的主机的ip和端口号。(用于发送时)

DatagramPacket方法:

  • getSocketAddress():获取发送端的ip地址。
  • getPort():获取发送端的端口
  • byte[] getData():获取数据报中的内容

udp回显服务器实现:
服务器端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;public class udpServer {//服务器端private DatagramSocket socket = null;public udpServer(int port) throws SocketException {socket = new DatagramSocket(port);}public void start() throws IOException {//System.out.println(socket.getPort());//returns the port to which the socket is connected  未连接套接字时 返回-1//如果想得到服务器端的端口 要使用socket.getLocalPort()System.out.println("服务器启动");//构建一个DatagramPacket来接收客户端发来的消息while(true){//创建一个DatagramPacket填充对象,用来接收从客户端发送来的数据报DatagramPacket reqPacket = new DatagramPacket(new byte[4096],4096);//如果没有数据报发送,receive发送会阻塞等待socket.receive(reqPacket);//转换成我们看得懂的字符串形式 ----- 客户端发送来的请求String request = new String(reqPacket.getData(),0,reqPacket.getLength());//服务器端做出响应String res = RESPONSE(request);//构建一个DatagramPacket将响应后的结果发送回客户端//注意需要有客户端socketAddressDatagramPacket respPacket = new DatagramPacket(res.getBytes(StandardCharsets.UTF_8),0,res.getBytes().length,reqPacket.getSocketAddress());//发送数据报socket.send(respPacket);System.out.println("服务器端口:"+socket.getLocalPort()+": 客户端[ip:"+respPacket.getAddress()+" 端口:"+reqPacket.getPort()+"] req:"+request+" res:"+res);}}public String RESPONSE(String req){return req;}public static void main(String[] args) throws IOException {udpServer server = new udpServer(8080);server.start();}
}

值得注意的是:DatagramSocket的getPort/getAddress方法,返回的都是连接方的端口和ip,并不是本地的。而DatagreamPacket的getPort/getAddress方法,返回的都是本地的端口和ip地址。如果你还没有连接成功时,打印socket.getPort(),虽然这时候你已经给出了指定端口,但这个方法的返回值是连接端的,还没连接时返回-1


客户端
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;public class udpClient {//目的端ipprivate String severIp;//目的端端口private int severPort;private DatagramSocket socket;public udpClient(String severIp,int severPort) throws SocketException {socket = new DatagramSocket();this.severIp = severIp;this.severPort = severPort;}public void start() throws IOException {Scanner sc = new Scanner(System.in);System.out.println("客户端启动");while(true){System.out.print(">>");String request = sc.nextLine();if(request.equals("exit")){System.out.println("退出");socket.close();return;}//给出消息发出的目的端ip和端口 (服务器ip端口)DatagramPacket reqPacket = new DatagramPacket(request.getBytes(StandardCharsets.UTF_8),request.getBytes().length,InetAddress.getByName(severIp),severPort);//发送socket.send(reqPacket);//接收响应DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//转换成字符串形式String res = new String(responsePacket.getData(),0, responsePacket.getLength());//打印响应System.out.println(res);}}public static void main(String[] args) throws IOException {udpClient client = new udpClient("127.0.0.1",8080);client.start();}
}

注意:当传服务器端的ip地址时,此时我们这里给的是一个字符串,但参数接收的是一个32位整数形式,所以我们需使用InetAddress.getName(String hostage)做一下转换


tcp
SeverSocket 

服务器端Socket API


构造方法:

  • SeverSccket(int port):创建一个服务器端流套接字Socket,并绑定到指定端口

SeverSocket的方法:

  • Socket accept():监听指定端口(创建时绑定的端口),如果有客户端连接后,返回一个服务端Socket对象,否则阻塞等待
  • void close():关闭套接字
Socket

客户端Socket,或服务器端的accept方法收到有客户端连接后返回的服务端Socket

无论是客户端还是服务器端,都是连接建立后,保存对端的信息


构造方法:

Socket(String severIp,int severPort):创建一个客户端Socket,与对应的主机端口建立连接


Socket的方法:

  • InetAddress():返回套接字所连接的地址
  • InputStream getInputStream():
  • OutputStream getOutStream():

ps:tcp是面向字节流传输的


tcp回显服务器实现

服务器端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;public class tcpSever {private ServerSocket socket;public tcpSever(int port) throws IOException {socket = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动");//与服务器建立连接 返回一个服务器端SocketSocket clickClient = socket.accept();processConnection(clickClient);}public void processConnection(Socket clientSocket){System.out.println("客户端上线[ip:"+clientSocket.getInetAddress().toString()+"  port:"+clientSocket.getPort()+"]");try(InputStream inputStream = clientSocket.getInputStream(); OutputStream outputStream = clientSocket.getOutputStream()) {while(true){//读取结果//输入流 会等待客户端输入东西 阻塞在这里 (通过Scanner的方法都会造成阻塞)Scanner sc = new Scanner(inputStream);if(!sc.hasNext()){//没有数据了 断开连接System.out.println("客户端下线[ip:"+clientSocket.getInetAddress()+"  port:"+clientSocket.getPort());socket.close();break;}//遇到换行/空白结束String req = sc.next();//服务器响应String resp = process(req);//OutputStream没有写String的方法//1.将其转换成字节数组//2.使用PrintWriter-----打印流-----字符打印流/字节打印流PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(resp);printWriter.flush();System.out.println("客户端:[req:"+req+" resp:"+resp+" ip:"+clientSocket.getInetAddress()+" port:"+clientSocket.getPort()+"]");}} catch (IOException e) {e.printStackTrace();}}public String process(String req){return req;}public static void main(String[] args) throws IOException {tcpSever sever = new tcpSever(8080);sever.start();}
}

客户端
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;public class udpClient {//目的端ipprivate String severIp;//目的端端口private int severPort;private DatagramSocket socket;public udpClient(String severIp,int severPort) throws SocketException {socket = new DatagramSocket();this.severIp = severIp;this.severPort = severPort;}public void start() throws IOException {Scanner sc = new Scanner(System.in);System.out.println("客户端启动");while(true){System.out.print(">>");String request = sc.nextLine();if(request.equals("exit")){System.out.println("退出");socket.close();return;}//给出消息发出的目的端ip和端口 (服务器ip端口)DatagramPacket reqPacket = new DatagramPacket(request.getBytes(StandardCharsets.UTF_8),request.getBytes().length,InetAddress.getByName(severIp),severPort);//发送socket.send(reqPacket);//接收响应DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//转换成字符串形式String res = new String(responsePacket.getData(),0, responsePacket.getLength());//打印响应System.out.println(res);}}public static void main(String[] args) throws IOException {udpClient client = new udpClient("127.0.0.1",8080);client.start();}
}

注意:

  1. 在tcp的Socket中,ip地址可以直接传字符串类型的,不需要像udpSocket那样转成32位整数形式
  2. 我们读通过next()读,写通过println写。这是设计好了的。使换行符变成我们的消息隔断符,使我们知道每一段消息的头和尾,解决粘包问题
  3. 在运行tcp回显服务器时,必须先开服务器端,再开客户端因为如果先开客户端的话,此时没有服务器与之相连,会抛异常------对应的即为tcp的是有连接的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/6836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玩comfyui踩过的坑之使用ComfyUI_Custom_NODES_ALEKPET翻译组件问题

环境: 秋叶安装包,安装ComfyUI_Custom_NODES_ALEKPET组件或者直接下载网盘中的包,直接解压包到comfyui根目录/custom_nodes/,重启后,按指导文件操作。 注意:网盘指导包中有配置好的流程json文件&#xff0…

Python爬虫:XPath解析爬取豆瓣电影Top250示例

一、示例的函数说明: 函数processing():用于处理字符串中的空白字符,并拼接字符串。 主函数程序入口:每页显示25部影片,实现循环,共10页。通过format方法替换切换的页码的url地址。然后调用实现爬虫程序的…

平衡二叉搜索树(AVL)旋转

单独开一章节介绍 RotateL 、 RotateR 及更复杂的 LR 和 RL 型旋转,更多是为了红黑树的旋转部分做铺垫;由于 AVL 树和红黑树发生旋转的判断标准不同 —— 分别为平衡因子和节点的颜色,两棵树左旋和右旋的在细节上会有一些差异,但从…

实现VUE DPlayer录像功能:Canvas加MediaRecorder

在做之前,以为DPlaye知道数据流,录像直接保存即可。结果是,根本没有录像功能。 怎么办呢?搜索了一番,给出的建议是使用Canvas加MediaRecorder来实现。大意是使用canvas,定时把视频画面刷过来;然…

Java基础教程(12)-Java中的IO流

IO是指Input/Output,即输入和输出。以内存为中心: Input指从外部读入数据到内存,例如,把文件从磁盘读取到内存,从网络读取数据到内存等。Output指把数据从内存输出到外部,例如,把数据从内存写入到文件,把数据从内存输出到网络等。流的输入和输出 Java程序通过流来完成输…

发表博客之:cutlass demo讲解,在 sm75 机器上用 cuda core计算 fp32 矩阵乘法!对cutlass 感兴趣的看客别走开!!

文章目录 [发表博客之:cutlass demo讲解,在 sm75 机器上用 cuda core计算 fp32 矩阵乘法!对cutlass 感兴趣的看客别走开!!](https://cyj666.blog.csdn.net/article/details/138469553)深入理解 cutlass 在 sm75 cuda c…

基于Spring Boot的线上交流互动系统设计与实现

基于Spring Boot的线上交流互动系统设计与实现 开发语言:Java框架:springbootJDK版本:JDK1.8数据库工具:Navicat11开发软件:eclipse/myeclipse/idea 系统部分展示 系统功能界面图,在系统首页可以查看首页…

「 网络安全常用术语解读 」通用安全通告框架CSAF详解

1. 简介 通用安全通告框架(Common Security Advisory Framework,CSAF)通过标准化结构化机器可读安全咨询的创建和分发,支持漏洞管理的自动化。CSAF是OASIS公开的官方标准。开发CSAF的技术委员会包括许多公共和私营部门的技术领导…

如何使用预训练的通用音频表示进行心脏杂音检测

心脏杂音检测是心血管疾病诊断中的一个重要方面,通过听诊器进行检查是常见方法,但对临床医生的经验依赖很大。为了减少心脏声音解释中对熟练临床医生的需求,探索自动化心脏听诊的深度学习方法很有必要。然而,尽管深度学习模型通常…

Redis Cluster集群方案什么情况下会导致整个集群不可用?

Redis 没有使用哈希一致性算法,而是使用哈希槽。 Redis 中的哈希槽一共有16384个,计算给定 密钥的哈希槽,我们只需要对密钥的 CRC16 去取 16384。假设集群中有A、B、C三个集群节点, 不存在复制模式下,每个集群的节点包…

、、、、、

、、 、 transient 关键字总结 1)transient修饰的变量不能被序列化;2)transient只作用于实现 Serializable 接口;3)transient只能用来修饰普通成员变量字段;4)不管有没有 transient 修饰&…

网络工程师必学知识:SSH登录抓包分析报文交互过程

网络工程师必学知识:SSH登录抓包分析报文交互过程 1.概述:2.SSH传输层协议:3.SSH用户认证协议:4.SSH连接协议:5.抓包看看:6.总结:1.概述: SSH(Secure Shell ,安全外壳协议),就是在不安全的协议外层再加一层安全外壳。比如说telnet+SSH=stelnet。 SSH由三个组件构成:…

ASP.NET网上书店

摘要 本设计尝试用ASP.NET在网络上架构一个电子书城,以使每一位顾客不用出门在家里就能够通过上网来轻松购书。本文从理论和实践两个角度出发,对一个具有数据挖掘功能电子书城进行设计与实现分析。论文首先较为详尽地介绍了面向对象分析与设计的有关概念…

C++实验五 : 类的继承 -----CUST

【题目】 1.定义person类,包括数据私有成员:姓名,性别;共用成员函数:带参数构造函数,display函数输出本类对象的所有数据成员值。 2.定义student类,保护继承person类;增加保护数据成…

docker desktop实战部署oracle篇

1、前言 oracle数据库官方已提供现成的镜像,可以直接拿来部署了。 由于项目中需要使用oracle数据库的分表功能,之前安装的是standard版本,无奈只能重新安装。网上查了一番,使用的方法都比较传统老旧:下载安装包手动安…

golang获取变量动态类型

类型断言:data.(Type) 类型断言是最常用的获取变量动态类型的方法之一。允许在运行时将接口值转换为其具体类型。 data 是一个接口类型的变量。 Type 是一个具体的类型。 这个表达式的含义是,如果 data 的底层值是 Type 类型,那么 value 将接…

深度学习之GAN网络

目录 关于GAN网络 关于生成模型和判别模型 GAN网路的特性和搭建步骤(以手写字体识别数据集为例) 搭建步骤 特性 GAN的目标函数(损失函数) 目标函数原理 torch.nn.BCELoss(实际应用的损失函数) 代码…

百度下拉框负面信息如何删除?

百度头条360等搜索引擎,作为人们获取信息的主要途径之一。然而,一些知名的企业或个人可能会面临在搜索的下拉框中出现负面信息的问题,这可能对其声誉和形象造成不良影响。小马识途营销顾问根据自身从业经验,针对这类情况提出以下建…

轻盈高效开源的WEB在线客服平台:Go-Fly

Go-Fly:即刻沟通,非凡服务,轻松连接每一个对话,让客服日常更简单高效!- 精选真开源,释放新价值。 概览 Go-Fly 是一款基于 Go 语言 构建的开源即时通讯与客服管理系统,专为寻求高效、可定制在线…

网安学习笔记day-15,交换机工作原理

交换机工作原理 交换机是二层设备,基于MAC表工作。 MAC地址是有48位二进制组成,也就是6字节,通常分为6段,用十六进制表示。 交换机通信方式: 单播:点对点发送数据 广播:向所有设备发送数据…