对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+多线程模拟实现一个简单的聊天室程序的更多相关文章

  1. [SignalR]一个简单的聊天室

    原文:[SignalR]一个简单的聊天室 1.说明 开发环境:Microsoft Visual Studio 2010 以及需要安装NuGet. 2.添加SignalR所需要的类库以及脚本文件: 3. ...

  2. JMS学习(四)-一个简单的聊天应用程序分析

    一,介绍 本文介绍一个简单的聊天应用程序:生产者将消息发送到Topic上,然后由ActiveMQ将该消息Push给订阅了该Topic的消费者.示例程序来自于<JAVA 消息服务--第二版 Mar ...

  3. 用ServletContext做一个简单的聊天室

    这里主要是ServletContext的一个特性:ServletContext是一个公共的空间,可以被所有的客户访问.由此可见ServletContext比cookie和session的作用范围要大[ ...

  4. 基于websocket实现的一个简单的聊天室

    本文是基于websocket写的一个简单的聊天室的例子,可以实现简单的群聊和私聊.是基于websocket的注解方式编写的.(有一个小的缺陷,如果用户名是中文,会乱码,不知如何处理,如有人知道,请告知 ...

  5. ASP.NET Signalr 2.0 实现一个简单的聊天室

    学习了一下SignalR 2.0,http://www.asp.net/signalr 文章写的很详细,如果头疼英文,还可以机翻成中文,虽然不是很准确,大概还是容易看明白. 理论要结合实践,自己动手做 ...

  6. 用c写一个小的聊天室程序

    1.聊天室程序——客户端 客户端我也用了select进行I/O复用,同时监控是否有来自socket的消息和标准输入,近似可以完成对键盘的中断使用. 其中select的监控里,STDOUT和STDIN是 ...

  7. 使用Beetle简单构建聊天室程序

    之前已经讲解了Beetle简单地构建网络通讯程序,那程序紧紧是讲述了如何发送和接收数据:这一章将更深入的使用Beetle的功能,主要包括消息制定,协议分析包括消息接管处理等常用的功能.为了更好的描述所 ...

  8. 如何用WebSocket实现一个简单的聊天室以及单聊功能

    百度百科中这样定义WebSocket:WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端.简单的说,We ...

  9. WebSocket介绍和一个简单的聊天室

    WebSocket是什么呢? WebSocket一种在单个 TCP 连接上进行全双工通讯的协议.WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范, ...

随机推荐

  1. js上 十二、函数初步-1

    11-1.引入(认识函数) ​ 引入: 说起函数,其实我们并不陌生,在初中数学中我们就接触过函数:例如我们所学的 y = 2X+1 ; 这是一个二元一次方程,也是我们数字中的函数: ​ 当我们每次输入 ...

  2. Eureka系列(一)Eureka功能介绍

    Eureka核心功能点 服务注册(register):   Client会发送一次Rest请求给Server端来实现注册,Server接受到请求会将服务信息存储起来,并将注册信息给同集群其他Serve ...

  3. python初学者-水仙花数简单算法

    输出"水仙花数".所谓水仙花是指一个3位数的十进制数,其各位数字的立方和等于该数本身.例如:153是水仙花数. 用for循环实现水仙花数的计算图如下所示: 1 for i in r ...

  4. 4.mysql profile的使用方法

    profile的使用 1.作用 使用profile可以对某一条sql性能进行分析 2.语法 mysql> show variables like '%profil%'; +----------- ...

  5. [LeetCode]313. Super Ugly Number超级丑数,丑数系列看这一道就行了

    丑数系列的题看这一道就可以了 /* 和ugly number2差不多,不过这次的质因子多了,所以用数组来表示质因子的target坐标 target坐标指的是这个质因子此次要乘的前任丑数是谁 */ pu ...

  6. CyclicBarrier(栅栏)的用法详解及与countDownLatch用法区别

    CyclicBarrier适用于这样的情况:你希望创建一组任务,它们并行的执行工作,然后在进行下一步步骤之前等待,直至所有任务都完成,它使得所有的并行任务都将在删栏出列队,因此可以一致的向前移动. 当 ...

  7. CF Grakn Forces 2020 1408E Avoid Rainbow Cycles(最小生成树)

    1408E Avoid Rainbow Cycles 概述 非常有趣的题目(指解法,不难,但很难想) 非常崇拜300iq,今天想做一套div1时看见了他出的这套题Grakn Forces 2020,就 ...

  8. SQL Server On Linux:基于实际项目案例,总结功能支持情况及相关问题解决方案,讲如何快速完成迁移

    上个月,有个朋友问我说Sql Sever向Mysql迁移有什么好的经验分享,他们公司客户明确提出不再提供Windows服务器,现在计划Mysql迁移.我说Mysql迁移成本太高了,不妨可以了解一下SQ ...

  9. thinkphp redis实现文章点赞功能并同步入mysql

    <?php namespace app\common\controller; use think\App; use think\facade\Cache; use think\facade\Db ...

  10. Typora笔记上传到播客时图片不显示问题解决(已解决)

    前言: ​ 相信我们都遇到过,使用Typora做笔记是一件非常令人舒服的事,然而,它却有一个非常难受的地方,那就是我们在做完笔记想要将其上传到自己的博客时,复制粘贴的图片无法显示.因为Typora复制 ...