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

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

    四 UDP

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

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

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

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

    1. //发送消息
    2. package send;
    3. import java.io.BufferedReader;
    4. import java.io.IOException;
    5. import java.io.InputStreamReader;
    6. import java.net.*;
    7. import java.nio.charset.StandardCharsets;
    8. public class UdpSend implements Runnable{
    9. DatagramSocket socket=null;
    10. BufferedReader reader=null;
    11. private int fromPort;
    12. private String toIp;
    13. private int toPort;
    14. public UdpSend(int fromPort, String toIp, int toPort) throws Exception {
    15. this.fromPort = fromPort;
    16. this.toIp = toIp;
    17. this.toPort = toPort;
    18. socket=new DatagramSocket(fromPort);
    19. reader=new BufferedReader(new InputStreamReader(System.in));
    20. }
    21. @Override
    22. public void run() {
    23. //准备数据控制台读取-->打包进去
    24. while (true) {
    25. try {
    26. String data = reader.readLine();
    27. byte[] datas;
    28. datas = data.getBytes();
    29. DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIp, this.toPort));
    30. socket.send(packet);
    31. if (data.equals("bye")) {
    32. break;
    33. }
    34. } catch (IOException e) {
    35. throw new RuntimeException(e);
    36. }
    37. //发送
    38. }
    39. socket.close();
    40. }
    41. }
    1. //接受消息
    2. package send;
    3. import java.io.IOException;
    4. import java.net.DatagramPacket;
    5. import java.net.DatagramSocket;
    6. import java.net.SocketException;
    7. import java.nio.charset.StandardCharsets;
    8. public class UdpReceive implements Runnable{
    9. DatagramSocket socket=null;
    10. private int port;
    11. private String msg;
    12. public UdpReceive(int port,String msg) throws Exception {
    13. this.port=port;
    14. this.msg=msg;
    15. socket=new DatagramSocket(port);
    16. }
    17. public void run(){
    18. while(true) {
    19. try {
    20. //准备接受包裹
    21. byte[] container = new byte[2024];
    22. DatagramPacket packet = new DatagramPacket(container, 0, container.length);
    23. //接受
    24. socket.receive(packet);
    25. //断开连接
    26. int length = packet.getLength();
    27. byte[] data = packet.getData();
    28. String receiveD = new String(data, 0, length);
    29. System.out.println(msg+":"+receiveD);
    30. if (receiveD.equals("bye")) {
    31. break;
    32. }
    33. } catch (IOException e) {
    34. throw new RuntimeException(e);
    35. }
    36. }
    37. socket.close();
    38. }
    39. }

    老师类:

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

    学生类:

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

    五 URL

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

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

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

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

  • 相关阅读:
    Unity Webgl发布的一些注意的点
    解析网页数据并且处理网页正则表达式与re模块
    基于MQTT的信息推送系统设计与实现
    站群服务器的特性和好处是什么
    python篇---python 用opencv读取rtsp视频流(二)
    C++核心编程(十九)继承的方式
    ControlNet原理及应用
    聊聊 Java 数据结构与算法中的堆最小堆和最大堆
    企业网络安全:威胁情报解决方案
    android studio 我遇到的Task :app:compileDebugJavaWithJavac FAILED问题及解决过程
  • 原文地址:https://blog.csdn.net/2301_80788553/article/details/139380508