利用JavaUDPSocket+多线程模拟实现一个简单的聊天室程序
对Socket的一点个人理解:Socket原意是指插座。家家户户都有五花八门的家用电器,但它们共用统一制式的插座。这样做的好处就是将所有家用电器的通电方式统一化,不需要大费周章地在墙壁上凿洞并专门接电线把家用电器和墙壁中的入户线接在一起。
将其对应于计算机中的网络通信:在TCP/IP网络的分层模型中,Socket是一组用于应用程序间进行网络通信的库函数,并位于应用层和传输层之间。有了Socket,一方面可以屏蔽底层通信软件和具体操作系统之间的差异,使任意两台安装了TCP/IP协议组件和套接字规范的计算机进行通信成为可能;另一方面,多种多样的应用程序就有了统一的网络编程的接口,而不需要和底层的传输层直接打交道,这就大大简化了网络编程的过程。
简单来说,Socket的通信机制就是,通信双方的应用程序都有Socket,将网络通信统一为Socket之间的通信,数据则在Socket之间通过IO流进行传输。
这里我们要模拟一个聊天室程序,众所周知,聊天室应用因其系统自身比较简单,不强调可靠性,因此适宜用UDP协议解决。
UDPSocket应用分为发送端和接收端两部分。对于发送端,该应用的执行流程为:
1.创建发送端Socket对象;
2.创建数据并打包;
3.发送数据;
4.释放传输资源。
对于接收端,该应用的执行流程为:
1.创建接收端Socket对象;
2.创建接收的数据包,换句话说将接收到的数据存放在何处;
3.接收数据;
4.解包,解析接收的数据,并打印在屏幕上;
5.释放传输资源。
此外,一个聊天室应用不仅要进行发送,也要进行接收,二者同时集成在同一应用上,因此必须通过多线程技术让发送和接收两个功能同时进行。
因此,对该程序的Java实现分为三部分:发送端线程,接收端线程,主函数。
发送端线程的Java代码实现为:
1 package chatroom;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import java.net.DatagramPacket;
7 import java.net.DatagramSocket;
8 import java.net.InetAddress;
9
10 public class SendThread implements Runnable {
11
12 private DatagramSocket ds;
13
14 public SendThread(DatagramSocket ds) {//发送端类的构造函数
15 this.ds = ds;
16 }
17
18 @Override
19 public void run() {
20 try {
21
22 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//将用户从键盘输入的数据装入字符缓冲输入流
23
24 String line = null;
25 System.out.println("发送端:欢迎来到聊天室.你想在这里说些什么?");
26 while ((line = br.readLine()) != null) {
27 byte[] bys = line.getBytes();
28 DatagramPacket dp = new DatagramPacket(bys, bys.length,InetAddress.getByName("192.168.1.102"), 12306);//生成要发送的报文,在本例中发送端的目的地址就是本机
29 ds.send(dp);//发送数据报
30 if ("886".equals(line)) {//如果发送的数据是“886”,则说明聊天结束
31 break;
32 }
33 }
34
35 ds.close();
36 } catch (IOException e) {
37 e.printStackTrace();
38 }
39 }
40
41 }
接收端线程的Java代码实现为:
1 package chatroom;
2
3 import java.io.IOException;
4 import java.net.DatagramPacket;
5 import java.net.DatagramSocket;
6
7 public class ReceiveThread implements Runnable {
8 private DatagramSocket ds;
9
10 public ReceiveThread(DatagramSocket ds) {//接收端类的构造函数
11 this.ds = ds;
12 }
13
14 @Override
15 public void run() {
16 try {
17 while (true) {//死循环,一直到收到886后跳出
18 byte[] bys = new byte[1024];//将接收的数据存于此处
19 DatagramPacket dp = new DatagramPacket(bys, bys.length);//创建要接收的数据包
20 ds.receive(dp);//接收数据
21 String ip = dp.getAddress().getHostAddress();
22 String s = new String(dp.getData(), 0, dp.getLength());
23 System.out.println("接收端:from " + ip + " data is : " + s);//打印接收到的数据
24 if ("886".equals(s)) {
25 break;
26 }
27 }
28 } catch (IOException e) {
29 e.printStackTrace();
30 }
31 }
32
33 }
主函数的Java实现代码为:
1 package chatroom;
2
3 import java.io.IOException;
4 import java.net.DatagramSocket;
5
6 public class ChatRoom {
7 public static void main(String[] args) throws IOException {
8 DatagramSocket dsSend = new DatagramSocket();//发送端Socket
9 DatagramSocket dsReceive = new DatagramSocket(12306);//接收端Socket,接收端端口号设置为12306
10
11 SendThread st = new SendThread(dsSend);//创建发送端
12 ReceiveThread rt = new ReceiveThread(dsReceive);//创建接收端
13
14 Thread t1 = new Thread(st);//创建发送端线程
15 Thread t2 = new Thread(rt);//创建接收端线程
16
17 t1.start();
18 t2.start();
19 }
20 }
实现效果如下图所示:

关于Java自带的Socket库函数与Linux自带的Socket系统调用之间的区别:
首先,二者提供的接口不同;
第二,Java的Socket库函数底层执行原理是JVM将Java程序解析出来的XML参数传递给C++程序,并将响应由C++程序回传给Java程序;
第三,Java程序通过JVM机制保证了优良的跨平台特性,同样的程序可以在任何操作系统下执行,而Linux下自带的Socket编程,写出的程序只能在Linux下运行。
利用JavaUDPSocket+多线程模拟实现一个简单的聊天室程序的更多相关文章
- [SignalR]一个简单的聊天室
原文:[SignalR]一个简单的聊天室 1.说明 开发环境:Microsoft Visual Studio 2010 以及需要安装NuGet. 2.添加SignalR所需要的类库以及脚本文件: 3. ...
- JMS学习(四)-一个简单的聊天应用程序分析
一,介绍 本文介绍一个简单的聊天应用程序:生产者将消息发送到Topic上,然后由ActiveMQ将该消息Push给订阅了该Topic的消费者.示例程序来自于<JAVA 消息服务--第二版 Mar ...
- 用ServletContext做一个简单的聊天室
这里主要是ServletContext的一个特性:ServletContext是一个公共的空间,可以被所有的客户访问.由此可见ServletContext比cookie和session的作用范围要大[ ...
- 基于websocket实现的一个简单的聊天室
本文是基于websocket写的一个简单的聊天室的例子,可以实现简单的群聊和私聊.是基于websocket的注解方式编写的.(有一个小的缺陷,如果用户名是中文,会乱码,不知如何处理,如有人知道,请告知 ...
- ASP.NET Signalr 2.0 实现一个简单的聊天室
学习了一下SignalR 2.0,http://www.asp.net/signalr 文章写的很详细,如果头疼英文,还可以机翻成中文,虽然不是很准确,大概还是容易看明白. 理论要结合实践,自己动手做 ...
- 用c写一个小的聊天室程序
1.聊天室程序——客户端 客户端我也用了select进行I/O复用,同时监控是否有来自socket的消息和标准输入,近似可以完成对键盘的中断使用. 其中select的监控里,STDOUT和STDIN是 ...
- 使用Beetle简单构建聊天室程序
之前已经讲解了Beetle简单地构建网络通讯程序,那程序紧紧是讲述了如何发送和接收数据:这一章将更深入的使用Beetle的功能,主要包括消息制定,协议分析包括消息接管处理等常用的功能.为了更好的描述所 ...
- 如何用WebSocket实现一个简单的聊天室以及单聊功能
百度百科中这样定义WebSocket:WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端.简单的说,We ...
- WebSocket介绍和一个简单的聊天室
WebSocket是什么呢? WebSocket一种在单个 TCP 连接上进行全双工通讯的协议.WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范, ...
随机推荐
- phpstorm ext-json is missing in composer.json
- 最新 obs-studio vs2019 开发环境搭建 代码编译
距离上一篇文章很久了,重新开始记录 OBS 开发相关情况,第一步就是环境搭建,第二步是构建 OBS-Studio VS 2019 开发环境搭建 下载软件和资源 软件安装没有特别说明的,下载安装即可. ...
- 手把手教你搭饥荒专用服务器(三)—MOD及其他高级设置
友情链接: 手把手教你搭饥荒专用服务器(一)-服务器准备工作 手把手教你搭饥荒专用服务器(二)-环境配置及基本使用 手把手教你搭饥荒专用服务器(三)-MOD及其他高级设置 手把手教你搭饥荒专用服务器( ...
- 将Maven镜像更换为国内阿里云仓库
1.国内访问maven默认远程中央镜像特别慢 2.用阿里的镜像替代远程中央镜像 3.大部分jar包都可以在阿里镜像中找到,部分jar包在阿里镜像中没有,需要单独配置镜像 换为国内镜像,让你感受飞一般的 ...
- SpringBoot入门到精通系列教程 - Filter/WebFilter
1. Filter简介 1.1. SpringBoot 中Filter的作用 1.2. @WebFilter 2. 基于@WebFilter的实现 2.1. SpringbootApplication ...
- break continue学习
1.break和continue必须使用在循环或者switch语句中 2.当break语句单独存在时.后面不要定义其他语句,因为后面的语句无法执行到 3.break跳出当前所在循环 4.break跳出 ...
- application.properties 中文乱码问题解决
1. 设置 File Encodings的Transparent native-to-ascii conversion为true,具体步骤如下:依次点击 File -> Settings -&g ...
- Redis-基础和应用篇
2020,到新公司这一年多以来,更新文章和总结知识的习惯被丢掉了.我复盘了下自己,原因不是公司技术氛围不好,也不是每天业务需求太多,其根本原因还是---惰性.作为我们技术人随着年龄的增长,精力也会被生 ...
- codeforces 1451D,一道有趣的博弈论问题
大家好,欢迎来到codeforces专题. 今天选择的问题是Contest 1451场的D题,这是一道有趣简单的伪博弈论问题,全场通过的人有3203人.难度不太高,依旧以思维为主,坑不多,非常友好. ...
- JavaScript正则表达式详解
在JavaScript中,正则表达式由RegExp对象表示.RegExp对象呢,又可以通过直接量和构造函数RegExp两种方式创建,分别如下: //直接量 var re = /pattern/[g | ...