当前位置:蜗牛素材网>综合资讯>图文>正文

websocket百万级连接java:张小飞的Java之路,第四十七章

人气:141 ℃/2024-02-14 10:57:57

写在前面:

视频是什么东西,有看文档精彩吗?

视频是什么东西,有看文档速度快吗?

视频是什么东西,有看文档效率高吗?

诸小亮:讲解了一些基础知识后,我们正是学习Socket

张小飞:Sokcet 是啥?

诸小亮:Socket:Java中为网络通信提供的一种机制,专业称:套接字

两个电脑进行通信时,数据在两个Sokcet之间通过IO传输

张小飞:具体该如何使用呢?

诸小亮:Java中使用 Sokcet 有两种方式——UDP和TCP

1. UDP通信

诸小亮:我们先看UDP

不需要建立连接,封装数据包,大小限制在64K以内 不可靠,安全性差,但速度快(就是发,对方是否接到,咱不管,比如:村里的喇叭)

张小飞:还是演示一下吧

1.1. 入门

诸小亮:没问题,首先是——接收端,看下面的代码

import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;/*** 接收端*/public class Receive { public static void main(String[] args) throws IOException { //1. 创建Socket,监听10000端口 DatagramSocket socket = new DatagramSocket(10000); //2. 通过数据包接收数据 byte[] arr = new byte[1024]; //3. 创建 DatagramPacket 对象,用来接收数据 DatagramPacket packet = new DatagramPacket(arr, arr.length); System.out.println("UDP接收端,准备接收数据。。。。。。"); //3.1 调用receive方法,如果收不到数据,程序会阻塞(也就是程序会停在这里,直到有数据) socket.receive(packet); //4. 通过DatagramPacket对象,解析收到的数据 String ip = packet.getAddress().getHostAddress(); int port = packet.getPort(); byte[] data = packet.getData(); //5. 转换成String String msg = new String(data,0, packet.getLength()); System.out.println("发送者IP:" ip); System.out.println("发送者端口:" port); System.out.println("消息内容:" msg); //6. 关闭Socket socket.close(); }}

张小飞:有了接收端,想必还有发送端把

诸小亮:那是必须的,下面就是发送端的代码

import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;public class Send { public static void main(String[] args) throws IOException { //1. 创建Socket,监听5000端口 DatagramSocket sendSocket = new DatagramSocket(5000); //如果不指定端口,会随机开启一个端口进行数据发送// DatagramSocket sendSocket = new DatagramSocket(); //2. 通过数据包封装数据 String msg = "亚瑟提着大宝剑冲过来了"; byte[] data = msg.getBytes(); //需要ip和端口号 DatagramPacket packet = new DatagramPacket(data, 0, data.length, InetAddress.getLocalHost(),10000); //3. 发送数据 System.out.println("UDP发送端,发送数据。。。。"); sendSocket.send(packet); //4. 关闭Socket sendSocket.close(); }}

诸小亮:先启动接收端,再启动发送端,结果:

1.2. 群聊

诸小亮:其实使用 UDP 可以实现群聊的功能

张小飞:哦?怎么实现?

诸小亮:UDP模式下,可以在局域网中发送广播消息,局域网中的每个电脑都能收到消息

IP地址中每个网段都有自己的广播地址,本机IP:192.168.31.173则 192.168.31 网段的广播地址是 192.168.31.255

张小飞:那,具体应该如何实现呢?

诸小亮:把上面的代码稍微改改就行了

1.2.1. 接收端

因为 receive 方法会阻塞,所以可以把 socket.receive(packet); 放到 while 循环中,一直接收消息

import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;public class Receive { public static void main(String[] args) throws IOException { //1. 创建Socket,监听10000端口 DatagramSocket socket = new DatagramSocket(10000); System.out.println("UDP接收端,准备接收数据。。。。。。"); while (true){ //2. 通过数据包接收数据 byte[] arr = new byte[1024]; DatagramPacket packet = new DatagramPacket(arr, arr.length); //receive方法,如果收不到数据会阻塞,也就是程序会停在这里直到有数据 socket.receive(packet); //3. 通过DatagramPacket对象,解析收到的数据 String ip = packet.getAddress().getHostAddress(); byte[] data = packet.getData(); //转换成String String msg = new String(data,0, packet.getLength()); System.out.println(ip ":" msg); } //4. 一直运行接收消息,所以不再关闭Socket// socket.close(); }}1.2.2. 发送端

发送端,接收用户的输入,然后发送广播

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;public class Send { public static void main(String[] args) throws IOException { //1. 创建Socket,监听5000端口 DatagramSocket sendSocket = new DatagramSocket(5000); //2. 接收用户输入 System.out.println("开始接收用户输入。。。。。。"); BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line=bufr.readLine())!=null){ byte[] buf = line.getBytes(); DatagramPacket dp = new DatagramPacket(buf,buf.length, InetAddress.getByName("192.168.31.255"),10000); sendSocket.send(dp); if("886".equals(line)) break; } //4. 关闭Socket sendSocket.close(); }}1.2.3. 结果

2. TCP通信

张小飞:您不是说还有 TPC 通信吗?这个怎么用?

诸小亮:TPC通信就比UDP要麻烦一些了

需要两台电脑建立连接,形成数据通道,在连接中进行大数据量传输因为必须建立连接,所以效率低,但安全性高,比如:打电话

张小飞:这么说,可以做一对一通信?

诸小亮:是的

2.1.1. 基本演示

诸小亮:TCP通信需要创建连接,分为客户端(Socket)、服务端(ServerSocket)

/*** 客户端*/public static void main(String[] args) throws IOException { //1. 创建Socket对象,指定目的IP和端口,用于创建连接 Socket socket = new Socket("127.0.0.1", 10000); //2. 发送数据 System.out.println("客户端发送数据。。。。。。"); OutputStream out = socket.getOutputStream(); out.write("亚瑟提着大宝剑冲过来了".getBytes()); //3. 关闭Socket socket.close();}

张小飞:这也不麻烦啊,比 UDP 简单多了

诸小亮:客户端是很简单,麻烦的地方在服务端,比如:

/*** 服务端*/public static void main(String[] args) throws IOException { //1. 创建ServerSocket,指定监听10000端口 ServerSocket serverSocket = new ServerSocket(10000); System.out.println("等待客户端连接。。。。。。"); //2. 获取Socket对象,如果能够获取到,说明连接成功 //注意:accept 方法会阻塞,直到有连接过来 Socket client = serverSocket.accept(); String ip = client.getInetAddress().getHostAddress(); int port = client.getPort(); System.out.println(ip "--" port ":连接成功。。。。。。"); //3. 通过客户端的IO流,获取数据 InputStream in = client.getInputStream(); byte[] arr = new byte[1024]; int len = in.read(arr); String msg = new String(arr,0,len); System.out.println(msg); //3.关闭资源 client.close(); serverSocket.close();}

诸小亮:先运行服务端,再运行客户端,结果:

2.1.2. 2. 客户端和服务端互相通信

张小飞:上面的代码服务端只能被动的接收数据啊,能不能让它们互相通信?

诸小亮:满足你

/*** 客户端*/public static void main(String[] args) throws IOException { //1. 创建Socket对象,指定目的IP和端口 Socket socket = new Socket("127.0.0.1", 10000); //2. 发送数据 System.out.println("客户端发送数据。。。。。。"); OutputStream out = socket.getOutputStream(); out.write("亚瑟提着大宝剑冲过来了".getBytes()); //3. 拿到InputStream,用于获取服务端返回的数据 InputStream in = socket.getInputStream(); byte[] arr = new byte[1024]; int len = in.read(arr); String msg = new String(arr,0,len); System.out.println("服务端返回:" msg); //4. 关闭Socket socket.close();}

/*** 服务端*/public static void main(String[] args) throws IOException { //1. 创建ServerSocket,指定监听10000端口 ServerSocket serverSocket = new ServerSocket(10000); System.out.println("等待客户端连接。。。。。。"); //2. 获取Socket对象,能够获取到,说明连接成功,accept会阻塞,直到新的连接过来 Socket client = serverSocket.accept(); String ip = client.getInetAddress().getHostAddress(); int port = client.getPort(); System.out.println(ip "--" port ":连接成功。。。。。。"); //通过客户端的IO流,获取数据 InputStream in = client.getInputStream(); byte[] arr = new byte[1024]; int len = in.read(arr); String msg = new String(arr,0,len); System.out.println(msg); //3. 返回信息给客户端 System.out.println("服务端端发送数据。。。。。。"); OutputStream out = client.getOutputStream(); out.write("吕布大招断路。。。。".getBytes()); //4.关闭资源 client.close(); serverSocket.close();}

先运行服务端,再运行客户端,结果:

张小飞:额。。。。,您这样确实是互相通信,不过,能不能做成QQ聊天那样子的?

诸小亮:也是可以的

2.1.3. 练习:一对一聊天2.1.3.1. 客户端

import java.io.*;import java.net.Socket;public class Client { public static void main(String[] args) throws IOException { //1. 创建Socket对象,指定目的IP和端口 Socket socket = new Socket("127.0.0.1", 20000); //开启一个守护线程,用于接收用户输入 receiveUserInput(socket); //接收服务端发送的数据 InputStream in = socket.getInputStream(); while (true){ byte[] arr = new byte[1024]; int len = in.read(arr); if(len == -1){//-1:表示结束 break; } String msg = new String(arr,0,len); System.out.println("server:" msg); //如果Server 发送过来的是 886,跳出循环,结束通讯 if("886".equals(msg)){ break; } } //4. 关闭Socket socket.close(); } private static void receiveUserInput(Socket socket) { Thread t = new Thread(new Runnable() { @Override public void run() { try{ //2. 接收用户输入,发送给Server System.out.println("开始接收用户输入。。。。。。"); BufferedReader reader = new BufferedReader( new InputStreamReader(System.in)); OutputStream out = socket.getOutputStream(); String line = null; while(true){ line = reader.readLine(); out.write(line.getBytes()); //如果输入886,跳出循环,结束通讯 if("886".equals(line)) break; } }catch (Exception e){ } } }); //设置为守护线程,主线程结束后,守护线程也结束 t.setDaemon(true); t.start(); }}2.1.3.2. 服务端

import java.io.*;import java.net.ServerSocket;import java.net.Socket;public class Server { public static void main(String[] args) throws IOException { //1. 创建ServerSocket,指定监听10000端口 ServerSocket serverSocket = new ServerSocket(20000); //2. 获取客户端连接,能够获取到,说明连接成功,accept会阻塞,直到新的连接过来 System.out.println("等待客户端连接。。。。。。"); Socket client = serverSocket.accept(); String ip = client.getInetAddress().getHostAddress(); System.out.println(ip " 连接成功。。。。。。"); //开启一个守护线程,用于接收用户输入 receiveUserInput(client); //通过客户端的IO流,获取数据 InputStream in = client.getInputStream(); while (true){ byte[] arr = new byte[1024]; int len = in.read(arr); if(len == -1){//-1表示结束 break; } String msg = new String(arr,0,len); System.out.println("client:" msg); //如果客户端发送的是886,跳出循环,结束通讯 if("886".equals(msg)){ break; } } //4.关闭资源 client.close(); serverSocket.close(); } private static void receiveUserInput(Socket client) { Thread t = new Thread(new Runnable() { @Override public void run() { try{ //2. 接收用户输入,发送给client System.out.println("开始接收用户输入。。。。。。"); //接收用户输入 BufferedReader bufr = new BufferedReader( new InputStreamReader(System.in)); String line = null; //给客户端发送数据 OutputStream out = client.getOutputStream(); while(true){ line = bufr.readLine(); out.write(line.getBytes()); //如果给客户端发送的是886,跳出循环,结束通讯 if("886".equals(line)) break; } }catch (Exception e){ } } }); //设置为守护线程,主线程结束后,守护线程也结束 t.setDaemon(true); t.start(); }}2.1.3.3. 3. 结果

上面代码,客户端和服务端,分别在局域网中的不同机器上运行

先运行 Server,再运行 Client

搜索更多有关“websocket百万级连接java:张小飞的Java之路,第四十七章”的信息 [百度搜索] [SoGou搜索] [头条搜索] [360搜索]
本网站部分内容、图文来自于网络,如有侵犯您的合法权益,请及时与我们联系,我们将第一时间安排核实及删除!
CopyRight © 2008-2024 蜗牛素材网 All Rights Reserved. 手机版