利用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所补充规范, ...
随机推荐
- mybatis-plus逻辑删除
MP(mybatis plus)已经大大简化了我们好多的开发操作,基本的增删改查都有了,包括代码生成等等,今天想说的是它的逻辑删除功能.我们都在数据库设计时候经常会有is字段,表示是否删除,为了留下员 ...
- B. Navigation System【CF 1320】
传送门 题目:简单理解就是,我们需要开车从s点到t点.车上有一个导航,如果当前点为x,则导航会自动为你提供一条从x到t的最短的路线(如果有多条,则随机选一条),每走到下一个点则会实时更新最短路线,当然 ...
- Python将word文档批量转PDF
前面有一篇<Python批量创建word文档(2)- 加图片和表格>的文章,利用这篇文章创建的word文档来批量转PDF文档.代码: 1 ''' 2 #python批量将word文档转换成 ...
- C# 生成图片验证码 图片缩略图 水印
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D ...
- [.NET] WCFDataService项目host到IIS上碰到的一个问题:数据库未能打开
今天在尝试重现OP一个问题的,遇到了一个新的问题. 项目坏境: WCF Data Service 5.6 Entity Framewrok 5(不用6的原因时要重新配置WCF项目) SQL Serve ...
- Multipass使用教程
一.Multipass介绍 Multipass是一种简单的虚拟机工具.它不仅使启用虚拟机变得快速简易,还使管理那些虚拟机变得异常简单,因此可以立即开始针对云.边缘.物联网或任何一种类型的技术进行开发. ...
- 死磕以太坊源码分析之txpool
死磕以太坊源码分析之txpool 请结合以下代码阅读:https://github.com/blockchainGuide/ 写文章不易,也希望大家多多指出问题,交个朋友,混个圈子哦 交易池概念原理 ...
- 使用swagger上传文件
经常使用swagger,可以通过设置[ProducesResponseType]标记接口的返回信息:swagger也能通过接口的参数列表,自动获得发送的数据结构信息. 不过有一个例外,就是上传文件的时 ...
- Ubuntu安装最新的SlickEdit软件--破解教程
最近主要工作系统转到LInux上面来了,Slickedit的安装破解也费了些事,今天将过程整理一下做个记录. 说明:SlickEdit pro V21.03 Linux 64位实测可用,MAC实测可用 ...
- spring: 我是如何解决循环依赖的?
1.由同事抛的一个问题开始 最近项目组的一个同事遇到了一个问题,问我的意见,一下子引起的我的兴趣,因为这个问题我也是第一次遇到.平时自认为对spring循环依赖问题还是比较了解的,直到遇到这个和后面的 ...