用java实现客服聊天+网络爬虫下载音乐(java网络编程,io,多线程)

一 灵感:

在2022年的暑假,也就是我即将迈进高三的那个暑假,我并没有察觉自己应该要学习了,还是和过往的暑假一样玩着王者荣耀,凌晨2点睡觉,中午12点起床。我依稀记得这种状态一直持续到8月19。然而离开学还有6天时。我肚子开始剧烈的疼痛。想了一切可以的办法来恢复但是无极于终。我上百度去搜索,搜到了些眉目,我也进入了济南一家肠胃医院的网站。下面一幅图就是我咨询的聊天。那么你知道这种技术是怎么实现的吗?就是基本的网上聊天。还有一些咨询网站的客服聊天。

二 通信基本概念--实现网上聊天理论

计算机网络

①我们目的是为了写出一个后台聊天,为什么还要了解计算机网络呢?因为聊天的本质就是在计算机网络下进行的。
②何为计算机网络?通过百科搜索我们能查询到计算机网络其实就是一些相互连接的、以资源共享为目的的、自治的计算机的集合。通俗点讲就是计算机网络就像一个巨大的邮局,不同的计算机就像不同的信箱,通过电线或无线信号来传递信息
③通信就要用各种协议比如早期的http协议和更加安全的Https协议(https经过加密和身份验证)。通信协议就像是一套规则和标准,确保计算机网络中的设备能够正确地发送和接收信息。它定义了数据如何被封装、地址信息如何被添加、以及错误如何被检测和纠正等。协议就是不同计算机遵循的规则。
④https和http只不过是应用层协议我们常见的两种。还有很多这里就不一一赘述。下面要讲的TCP,UDP是传输层的协议与我们今天要讲的聊天密切相关。
⑤每个计算机都有它的IP就是地址。有各自的IP我们才能传送数据。IPv6格式能分配的地址非常多据说可以为地球的每一粒沙子分配地址。
⑥端口就是用来区分每个软件或进程的。在下面代码中我们会用到。
⑦接下来的测试将在本地进行。要用到特殊地址127.0.0.1。

三 TCP

TCP实现聊天:分为客户端和服务端。客户端用来构造连接,发送信息。服务端用来接受信息,输出信息。

我们用TCP实现简单文字传输:
//客户端
package chat;import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;public class TcpClientDemo1 {public static void main(String[] args) {try {//获取服务端的地址InetAddress serverIp = InetAddress.getByName("127.0.0.1");int port = 9999;//创见一个Socket连接Socket socket = new Socket(serverIp, port);  //一步化简--》  Socket socket = new Socket(InetAddress.getName(""), 5555);//发送信息创建io流OutputStream os=socket.getOutputStream();os.write("你好".getBytes());os.close();} catch (Exception e) {e.printStackTrace();}}
}
//服务端package chat;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;//服务器端
public class TcpServerDemo1 {public static void main(String[] args) {ByteArrayOutputStream bao=null;//地址 端口号try {ServerSocket serverSocket = new ServerSocket(9999);//等待客户端连接过来Socket socket=serverSocket.accept();//读取客户端的信息InputStream is=socket.getInputStream();//管道流bao=new ByteArrayOutputStream();byte[]buffs=new byte[1024];int len;while((len=is.read(buffs))!=-1){bao.write(buffs,0,len);System.out.println(bao.toString());//关闭}}catch(Exception e){e.printStackTrace();}finally{if(bao!=null) {try {bao.close();} catch (Exception e) {e.printStackTrace();}}}}
}
我们用TCP实现文件上传(与上面代码很是相似但略有不同):
//客户端package file;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;//文件上传
public class TcpClientDemo2 {public static void main(String[] args) {try {//获取连接Socket socket=new Socket(InetAddress.getByName("127.0.0.1"),5555);//文件输出--》创建一个输出流OutputStream os=socket.getOutputStream();//读取文件FileInputStream fis=new FileInputStream(new File("C://Users//hp//OneDrive//图片//本机照片//微信图片_20240227182056.jpg"));int len;byte[]buffs=new byte[2014];while((len=fis.read(buffs))!=-1){os.write(buffs,0,len);//写进来再输出去}//写一个传送完成的标志,告诉服务器已经结束了socket.shutdownOutput();//当传送完成时应该输出语句输送成功InputStream is=socket.getInputStream();//管道输出ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();int len1;byte[]buffs1=new byte[2024];while((len1=is.read(buffs1))!=-1){byteArrayOutputStream.write(buffs1,0,len1);}System.out.println(byteArrayOutputStream.toString());byteArrayOutputStream.close();
is.close();fis.close();os.close();socket.close();} catch (Exception e) {e.printStackTrace();}}}
//服务端package file;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;public class TcpServerDemo2 {public static void main(String[] args) {try {//服务端的端口ServerSocket serverSocket=new ServerSocket(5555);//等待接受,阻塞式监听会一直等待Socket socket=serverSocket.accept();//获取输入流InputStream is=socket.getInputStream();//文件输出FileOutputStream fos=new FileOutputStream(new File("receive.jpg"));  //命了个名int len;byte[]buffs=new byte[2024];while((len=is.read(buffs))!=-1){fos.write(buffs,0,len);//写进来输出}//输出输出完成//输出流OutputStream os=socket.getOutputStream();os.write("输送成功".getBytes());fos.close();is.close();socket.close();serverSocket.close();} catch (Exception e) {e.printStackTrace();}}}

文件上传成功后,我们文件会出现在最下面如图所示:

四 UDP

既然上面已经通过TCP实现交流了为什么还要UDP实现交流呢?这不得不提一下两者的差别。TCP协议需要进行连接,而UDP协议不需要进行连接,随便传送。

//建立一个Socket
DatagramSocket socket=new DatagramSocket();
//建立一个数据包
String msg="新年快乐";
InetAddress localhost=InetAddress.getByName("localhost");
int port=5555;
DatagramPacket packet=new DatagramPacket(msg.getBytes(),msg.getBytes().length,localhost,port);
//发送数据包
socket.send(packet);
//关闭
socket.close();
  //开发端口DatagramSocket socket=new DatagramSocket(5555);//接受数据包byte[]buffs=new byte[1024];DatagramPacket packet=new DatagramPacket(buffs,0,buffs.length);socket.receive(packet);System.out.println(packet.getAddress().getHostAddress());System.out.println(new String(packet.getData(),0, packet.getLength()));

通过上面的代码可以发现:UDP在客户端先建立一个socket连接,建立包,发送包的过程。然而没有了服务端这一概念,不需要进行连接而是接受包输出包的过程。

由此我们可以实现互发消息,通过多线程。

//发送消息package send;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.nio.charset.StandardCharsets;public class UdpSend implements Runnable{DatagramSocket socket=null;BufferedReader reader=null;private int fromPort;private String toIp;private int toPort;public UdpSend(int fromPort, String toIp, int toPort) throws Exception {this.fromPort = fromPort;this.toIp = toIp;this.toPort = toPort;socket=new DatagramSocket(fromPort);reader=new BufferedReader(new InputStreamReader(System.in));}@Overridepublic void run() {//准备数据控制台读取-->打包进去while (true) {try {String data = reader.readLine();byte[] datas;datas = data.getBytes();DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIp, this.toPort));socket.send(packet);if (data.equals("bye")) {break;}} catch (IOException e) {throw new RuntimeException(e);}//发送}socket.close();}}
//接受消息package send;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;public class UdpReceive implements Runnable{DatagramSocket socket=null;private int port;private String msg;public UdpReceive(int port,String msg) throws Exception {this.port=port;this.msg=msg;socket=new DatagramSocket(port);}public void run(){while(true) {try {//准备接受包裹byte[] container = new byte[2024];DatagramPacket packet = new DatagramPacket(container, 0, container.length);//接受socket.receive(packet);//断开连接int length = packet.getLength();byte[] data = packet.getData();String receiveD = new String(data, 0, length);System.out.println(msg+":"+receiveD);if (receiveD.equals("bye")) {break;}} catch (IOException e) {throw new RuntimeException(e);}}socket.close();}}

老师类:

package send;public class tackTeacher {public static void main(String[] args) throws Exception {new Thread(new UdpSend(4444,"localhost",7777)).start();new Thread(new UdpReceive(8888,"学生")).start();}}

学生类:

package send;public class tackStudent {public static void main(String[] args) throws Exception {new Thread(new UdpSend(5555,"localhost",8888)).start();new Thread(new UdpReceive(7777,"老师")).start();}
}

五 URL

URL其实就相当于网络爬虫,下载网络视频音乐等。

这里是一段下载音乐的代码:

package U;import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.*;public class UrlDown {public static void main(String[] args) throws Exception {//下载地址URL url=new URL("\n" +"https://m804.music.126.net/20240601202251/50656d3a6d5b5489905b09e4ada8bef2/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/34873299362/7d37/4c2f/3640/245ede6e6294337d349d85532c0abcc3.m4a");//连接到这个资源HttpURLConnection connection=(HttpURLConnection)url.openConnection();//输入InputStream is=connection.getInputStream();FileOutputStream fos=new FileOutputStream("f.m4a");byte[]buffs=new byte[1024];int len;while((len=is.read(buffs))!=-1){fos.write(buffs,0,len);}//断开fos.close();is.close();connection.disconnect();}
}

如果包最下面出现如图情况就说明下载完成了。如果还有什么不懂的地方或者没有实现,可以私信我或在评论区留下您的问题。

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

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

相关文章

【MySQL】Linux安装MySQL

一、center OS环境准备 为了在Linux系统中查看MySQL5.8与8.0版本的区别 我们要准备两个虚拟机,需要的软件:VMware和CentOS7 因为博主之前在学习redis的时候已经安装过一个虚拟机了,所以我就直接克隆了一个CentOS2.0 修改mac地址&#xff0…

STM32作业实现(二)串口控制led

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…

用python画一艘“福建舰”

import turtle # 设置画布和画笔 screen turtle.Screen() screen.bgcolor("white") pen turtle.Turtle() pen.speed(10) pen.color("blue") pen.penup() # 航母主体(简化为一个矩形) pen.goto(-200, 0) pen.pen…

路由和交换网络技术有哪些内容?

1. 路由器和交换机的基本概念:了解路由器和交换机的定义、功能和区别,以及它们在网络中的重要作用。 2. 路由协议:掌握常见的路由协议,如静态路由、动态路由和默认路由,以及它们的工作原理和使用场景。 3. VLAN和IP地址…

深入理解Java中的List集合:解析实例、优化技巧与最佳实践

一:List 集合的基础 1.1 什么是 List 集合? List 集合是 Java 集合框架中的一种有序、可重复的数据结构,它继承自Collection 接口,允许存储多个元素。 与数组不同,List 集合的大小是动态可变的,可以根据…

通过指针变量访问整型变量

有两个与指针变量有关的运算符: (1)&:取地址运算符。 (2)*:指针运算符(或称间接访问运算符)。 例如:&a为变量a的地址,*p为指针变量p所指向的存储单元。 编写程序: 运行结果…

【面试经典150题】移除元素

目录 一.移除元素 一.移除元素 这题的思路非常清晰&#xff0c;可以使用迭代器遍历找到需要删除的元素使用erase删除即可&#xff1a; #include<iostream> #include<vector>using namespace std;class Solution { public:int removeElement(vector<int>&…

设计模式(六)结构型模式---桥接模式

文章目录 桥接模式简介结构优点UML图具体实现UML图代码实现 桥接模式简介 桥接模式是一种将抽象与实现分离&#xff0c;使它们独立变化。然后利用组合关系来代替继承关系&#xff0c;大大的降低了抽象和实现的耦合度的设计模式。实际使用&#xff1a; JDBC源码分析&#xff0c…

C语言习题~day26

1.以下关于枚举的说法&#xff0c;哪个是正确的&#xff1f; A.枚举类型可以具有浮点数作为枚举值。 B.枚举类型在内存中存储为整数。 C.枚举类型可以包含字符串作为枚举值。 D.枚举类型不能作为函数的参数传递。 B 2.下面代码的结果是&#xff1a;&#xff08; &#xff0…

Kotlin 继承和实现

文章目录 前言继承&#xff08;extend&#xff09;实现&#xff08;implement&#xff09;继承与实现 前言 在 Kotlin 中&#xff0c;继承和实现都是在类名后使用冒号:&#xff0c;后边加上其他类或接口的名称来表示&#xff0c;二者之间写法没有太大区别&#xff08;类需要加…

Xcode下载安装

1.Xcode可用版本判断&#xff1a; 2.Xcode下载安装&#xff1a; 方案1:AppStore 下载更新 若方案1失败则 方案2:指定版本Xcode包下载解压安装 苹果下载 3.Xcode命令行工具插件安装 xcode-select --install 备注&#xff1a; xcode_x.x.x.xip(压缩包存在时效性(使用前24h/…

Mac专用投屏工具:AirServer 7 for Mac 激活版下载

AirServer 7 是一款在 Windows 和 macOS 平台上运行的强大的屏幕镜像和屏幕录制软件。它能够将 iOS 设备、Mac 以及其他 AirPlay、Google Cast 和 Miracast 兼容设备的屏幕镜像到电脑上&#xff0c;并支持高质量的录制功能。总的来说&#xff0c;AirServer 7 是一款功能全面的屏…

Mybatis编写SQL

文章目录 一、用注解编写1.1 增普通增加获取自增ID 1.2 删和改1.3 查单表查询多表查询 二、用xml编写2.1 使用xml的流程2.2 增普通增加获取自增ID 2.3 删 和 改2.4 查 三、#{} 和 ${}3.1 #{} 、${}3.1 预编译 SQL 、即时编译SQL 两种写法是可以同时存在的 一、用注解编写 1.1 …

QuillEditor+vue3 本身不支持行高的配置,那么如何配置行高?

通过查阅官方文档和众多资料发现&#xff0c;在QuillEditor的使用中&#xff0c;行高的配置并不像加粗、斜体等样式仅需配置关键词即可&#xff0c;那么QuillEditor的行高如何配置呢&#xff1f; 首先我们仍然要在富文本的配置的modules中写入行高的配置项 const myOptions …

linux bind函数

bind函数的目的是让把客户端对应的端口(port)地址和ip地址绑定到客户端 [参考](Linux之bind 函数&#xff08;详细篇&#xff09;_linux bind函数-CSDN博客)

Text1作业

Text1作业 Text1作业 题量: 16 满分: 100.0 一. 单选题&#xff08;共5题&#xff09; 1【单选题】A______ is a functional unit that interprets and carries out instructions.&#xff08;5.0分&#xff09; A memoryB processorC storageD network 2【单选题】A____…

mediasoup基础概览

提示&#xff1a;本文为之前mediasoup基础介绍的优化 mediasoup基础概览 架构&#xff1a;2.特性&#xff1a;优点缺点 3.mediasoup常见类介绍js部分c 4.mediasoup类图5.业务类图 Mediasoup 是一个构建在现代 Web 技术之上的实时通信&#xff08;RTC&#xff09;解决方案&#…

c语言多进程编程实例:深度探索与实用技巧

c语言多进程编程实例&#xff1a;深度探索与实用技巧 在C语言编程中&#xff0c;多进程编程是实现并发执行和资源共享的重要手段。本文将通过四个关键方面、五个核心要点、六个进阶技巧以及七个实践建议&#xff0c;带领读者深入理解C语言多进程编程的精髓。 四个方面&#x…

快速排序详讲(两种方法)

目录 原理 实现方式 正常实现 理由 先从右到左&#xff0c;在从左到右 先从左到右&#xff0c;先从右到左 挖坑法 效率 优化 测试 代码 原理 快速排序是将最左侧的数字当作关键数字&#xff0c;将关键数字放在对应位置&#xff0c;且关键数字左侧均大于它&#xff…

TRDB是啥

传统关系型数据库 TRDB:“Traditional Relational Database”,即“传统关系型数据库”。 关系型数据库,是指采用了关系模型来组织数据的数据库,其以行和列的形式存储数据,以便于用户理解,关系型数据库这一系列的行和列被称为表,一组表组成了数据库。