对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. 行业动态 | 每日处理2500万事务数据的IoT解决方案

    借助DataStax Enterprise和其他开源的解决方案,Locstat为它的用户提供了创新的IoT解决方案,并将数据分析时间由2-3周降至数分钟内,从而快速生成用于分析的图数据.不仅如此,现在 ...

  2. SpringBoot从入门到精通教程(二)

    SpringBoot 是为了简化 Spring 应用的创建.运行.调试.部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖 ...

  3. Java基础知识面试题详解(2019年)

    文章目录 1. 面向对象和面向过程的区别 2. Java 语言有哪些特点? 3. 关于 JVM JDK 和 JRE 最详细通俗的解答 JVM JDK 和 JRE 4. Oracle JDK 和 Ope ...

  4. 程序运行慢?你怕是写的假 Python

    Python程序运行太慢的一个可能的原因是没有尽可能的调用内置方法,下面通过5个例子来演示如何用内置方法提升Python程序的性能. 1. 数组求平方和 输入一个列表,要求计算出该列表中数字的的平方和 ...

  5. 【程序包管理】篇章3:CentOS平台下软件包安装方法总结

    1.软件包安装前的学习:程序包管理的基础知识 2.程序包安装的方法介绍: rpm文件的二进制包安装:Linux程序包管理之rpm安装总结 yum安装:Linux程序包管理之yum源安装 链接:本地yu ...

  6. 简单session实现

    简单的session校验实现 利用拦截器实现 package com.ryh.blog.intecepter; import org.springframework.core.Ordered; imp ...

  7. C# 使用 log4net 日志组件

    一. 什么是 log4net  Apache log4net 库是帮助程序员将日志语句输出到各种输出目标的工具,它是从Java中的Log4j迁移过来的一个.Net版的开源日志框架.log4net 的一 ...

  8. Media Queries媒体查询

    Media Queries能在不同的条件下使用不同的样式,使页面在不同在终端设备下达到不同的页面效果.Media Queries有其自己的使用规则.一个媒体查询由一个可选的媒体类型和媒体特性表达式,使 ...

  9. Python基础(中篇)

    本篇文章主要内容:数据类型的常用方法,条件语句,循环语句. 在开始正篇之前我们先来看看上一篇留下的题目. 题目: 定义一个字典a,有两个键值对:一个键值对key是可乐,value是18:另一个键值对k ...

  10. 并发编程之JMM&Volatile(一)

    并发 很多程序员应该对并发一词并不陌生,并发如同一把双刃剑,如果使用得当,可以帮助我们更好的压榨硬件的性能,反之,也会产生一些难以排查的问题.这里,先简单介绍下并发的几个基本概念. 进程与线程 进程: ...