JAVA 网络编程 - 实现 群聊 程序
Posted cyjiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 网络编程 - 实现 群聊 程序相关的知识,希望对你有一定的参考价值。
在实现 这个 程序之前, 我们 需要 了解 一些 关于 Java 网络 编程 的 知识.
基本 的 网络知识:
网络模型
OSI (Open System Interconnection 开放系统互连) 参考模型.
TCP/IP 参考模型.
网络通讯要素
IP 地址
端口号
传输协议
*** 网络编程 指的就是 网络技术 和 IO 技术的综合.
网络参考模型.
OSI 参考模型 TCP/IP
应用层---------------------
表示层 应用层
会话层---------------------
传输层 传输层
网络层 网际层
数据链路层-----------------
主机 至 网络层
物理层--------------------
网络 7 层
*** ipconfig/all 物理地址. . . . . . . . . . . . . : 54-3H-4L-7P-44-JK , 这个地址 是全球 唯一的. (这个 是 网卡的标识号)
IP 地址: InetAddress
网络中 设备的标识. 例如: 192.168.1.23 (这个网段 通常用于 局域网) 最大 为 255
不易记忆, 可用主机名(更易于记忆) 例如: 我的 主机名 FDSJLAKJFL 和 IP 地址对应, 也是 唯一的.
每一台计算机中 都有网卡(MAC)地址, 这个地址 默认 绑定的 一个 IP 地址, 默认就是 127.0.0.1 (如果 访问的 主机是自己的 话, 就可以用 这个 地址来访问.)
本地 回环地址: 127.0.0.1 主机名: localhost
端口
用于标识 进程的 逻辑地址, 不同进程的标识.
有效端口: 0!65535, 其中 0 ~ 1024 是 系统使用 或 保留端口.
*** 传输协议
通讯的规则
常见协议: TCP, UDP
// *** 检测 网卡是否正常工作.
C:Users>ping 127.0.0.1
正在 Ping 127.0.0.1 具有 32 字节的数据:
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
127.0.0.1 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 0ms,最长 = 0ms,平均 = 0ms
如果 不是以上结果, 而是 失败了话, 就很有可能 是 网卡 出了问题.
// *** 可用于 访问 的网站 有很多 游戏广告, 可以将 这些 游戏广告的 域名 写到 hosts 文件中来. 就打不开 哪些 广告 网站, 只会 打开自己 设置的 hosts 文件 中的 IP 地址 所对应的 .
*** 配置 hosts 文件. 127.0.0.1 www.game.com.cn
本机中 没有此资源, 表示 该页面 无法显示.
序列号, 将 校验的 网站的 IP 地址 改为 自己 电脑的 IP 地址, 自己电脑中 是没有 这个 校验 程序的, 所以 就 哦了. 软件 每次 联网 校验 都没用, 所以就可以免费使用了.
不过 首先要知道 校验的网站的 域名是什么.(360 地址列表)
端口
*** 在计算机中, 就 0 ~ 65535 六万 多个 端口 是可以用的, 而 0 ~ 1024 这些端口 尽量不要用, 这些 端口 很多 都 对应着 Windows 系统中的 应用程序,
*** 你要用了 , Windows 就用不了了. 数字标识 得 具有唯一性, 不能 两个 程序 用一个 端口.
关于 TCP, UDP, Socket, IO 流的 了解 和 使用:
TCP/UDP
UDP (数据报文包协议)
将 数据及 源 和 目的 封装成 数据包中, 不需要建立连接. 面向 无连接.
每个 数据包的 大小 限制在 64k 内.
因 无连接, 是 不可靠协议 不管对方在不在, (没 连接上 也行), 打个包(64k 内), 放个地址,就送.
不需要建立连接, 速度快. : 好处
TCP (传输控制协议)
建立连接, 形成传输数据的通道. 保证对方在,(建立连接)
在连接中 进行大数据量 传输.
通过 三次 握手 完成 连接, 是 可靠协议. 你在吗? 我在. 我知道了. 三次握手.
必须建立 连接, 效率 会 稍低.
例如: TCP 就 相当于 打电话. UDP 就相当于 对讲机.
Socket
Socket 就是为 网络服务提供的一种 机制.
通信的 两端都有 Socket.
网络通信 其实就是 Socket 间的通信.
数据在 两个 Socket 间通过 IO 传输.
TCP 用的 是 客户端 和 服务端 进行通讯的.
UDP 分的是 发送 和 接收.
TCP 分的是 客户端 和 服务端.
关于 局域网 中的 广播地址:
255 广播 地址, 我发一句, 到 广播地址, 广播 地址 发给 这个 网段中 所有的 主机, 你看到,我也会看到, 就实现了 聊天 功能,只要我们在 同一个 局域网中.就哦了.
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 UDPChatTest { public static void main(String[] args) throws IOException{ /* * * 案例一: 通过 UDP 实现 群聊程序. * * 思路: * * 这个程序中 既有 收 又有 发 , 那么 需要同时 执行, 需要使用 多线程 技术. * * 一个线程 负责发, 一个 线程 负责收, 需要两个任务.(线程任务); * * */ // 发送端 的Socket , 接收端 的 Socket; DatagramSocket sendSocket = new DatagramSocket(); DatagramSocket receSocket = new DatagramSocket(10000); // 创建 任务 对象. Send send = new Send(sendSocket); Rece rece = new Rece(receSocket); // *** 创建 线程 并开启. Thread t1 = new Thread(send); // *** 发 Thread t2 = new Thread(rece); // *** 收 t1.start(); t2.start(); } } /* * * * 255 广播 地址, 我发一句, 到 广播地址, 广播 地址 发给 这个 网段中 所有的 主机, 你看到,我也会看到, 就实现了 聊天 功能,只要我们在 同一个 局域网中.就哦了. * * * */ // 发送任务 这里 先把 架子 搭起来 , 都需要 哪些 东西. class Send implements Runnable{ private DatagramSocket ds; public Send(DatagramSocket ds) { this.ds = ds; } @Override public void run() { // System.out.println("UDP2 发送端 run "); // *** 这里写的端口号 如果 已经 有 程序在使用了, 就不能用 这个 端口号了, 程序会启动不起来, 因为 端口号 冲突了.(会 发生 地址 已被 占用 异常.) // *** 数据来自于 键盘录入. try { BufferedReader bufin = new BufferedReader(new InputStreamReader(System.in)); // *** 键盘 录入 也是 阻塞式的, 你没录入 就不会 停止, 一直 阻塞在 这里. String line = null; while((line = bufin.readLine()) != null) { byte[] buf= line.getBytes(); // *** 将数据 转成 数组. DatagramPacket dp = new DatagramPacket( buf,buf.length,InetAddress.getByName("192.168.1.255"),10000); // *** 这里的 地址 可以写成 其他人的 IP 地址 和 端口号 ,就可以 进行 聊天了. ds.send(dp); // *** 既然是 键盘 录入, 那么 就一定要 加一个 结束 标记. if("886".equals(line)) { break; } } // *** 关闭 资源 ds.close(); } catch (IOException e) { } } } // 接收任务. class Rece implements Runnable{ private DatagramSocket ds; public Rece(DatagramSocket ds) { this.ds = ds; } @Override public void run() { // System.out.println("udp2 接收端 run "); while(true) { try { byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); // *** 阻塞, 如果 没有接收到 数据 就会 一直阻塞在这里. String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String text = new String(dp.getData(),0,dp.getLength()); System.out.println(ip + ":" + port+ ":" + text); if(text.equals("886")) { System.out.println(ip + "...离开 聊天室" ); } }catch(IOException e) { } // ds.close(); *** 一直在 接收, 收 别人 发过来的 数据, 我就不用 关闭 资源了. } } }
这个 程序 使用的 环境 是 在一个 局域网中, 只要 启动 这个 程序, 发的 消息 会通过 255 这个 广播 地址 发送到 在这个 网段内的 主机中, 那么 大家 就都可以 看见, 就可以 实现 聊天 功能, 当然 ,
IP 地址 也可以使用 你自己的 主机 IP 地址, 只是 你自己 的 IP 地址 是不具备 广播的 功能的, 别人 还是 可以 发送给 你信息, 你肯定 可以 看到, 但是 别人 那里 只是 显示 发出了 消息, 不会 显示 回复的 消息, 因为 我写的程序 发送的 IP 地址 不是 给他的.
感谢 毕
以上是关于JAVA 网络编程 - 实现 群聊 程序的主要内容,如果未能解决你的问题,请参考以下文章
第97题JAVA高级技术-网络编程16(简易聊天室11:实现客户端群聊)