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


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();
-
- }
- }
-
- }
- }
- }
- //客户端
-
-
- 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();
- }
- }
-
- }
文件上传成功后,我们文件会出现在最下面如图所示:

既然上面已经通过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));
-
- }
-
- @Override
- public 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其实就相当于网络爬虫,下载网络视频音乐等。
这里是一段下载音乐的代码:
- 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();
-
- }
- }
如果包最下面出现如图情况就说明下载完成了。如果还有什么不懂的地方或者没有实现,可以私信我或在评论区留下您的问题。
