热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[Java聊天室服务器]实战之八读写循环(客户端)

前言学习任何一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定----也就是人们常说的“多谋善断;本系列虽然涉及的是socket相关的知识,但学习之前,更想和广

前言

学习任何一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的“多谋善断";本系列虽然涉及的是socket相关的知识,但学习之前,更想和广大程序员分享的是一种心境,:学习是一个循序渐进的过程,心态应该随时调节,保持戒骄戒躁的状态。比如最近在看网易公开课MIT《算法导论》,老师提到,学习算法之前要计算机数学+离散数学+概率论等课程的知识,所以一直学不好算法的程序员不妨从基础入手,这都是中国式教育惹的祸啊!(此处省略一万字......)


项目源码:Socket_Chat

目录

      • [Java聊天室服务器]实战之一 开篇介绍(已完成)
      • [Java聊天室服务器]实战之二 监听类(已完成)
      • [Java聊天室服务器]实战之三 接收循环(已完成)
      • [Java聊天室服务器]实战之四 线程类(已完成)
      • [Java聊天室服务器]实战之五 读写循环(服务端)(已完成)
      • [Java聊天室服务器]实战之六 去除死链接(已完成)
      • [Java聊天室服务器]实战之七 客户端类(已完成)
      • [Java聊天室服务器]实战之八 读写循环(客户端)(已完成)

正文

读写循环(客户端)

在服务端,我们已经有了读写循环,还需要在客户端创建。目的是一样的:读取传入的信息,处理它,作为响应可能会写入一些特征返回到服务端。然后一直重复着做这些事情。


这是客户端看起来的样子:

// 后台线程运行:从其他窗口显示信息
public void run() {
try {
// 接受信息一个到一个,一直循环
while (true) {
// 获取下一条信息
String message = din.readUTF();
// 打印在文本窗口中
ta.append( message+"\n" );
}
} catch( IOException ie ) { System.out.println( ie ); }
}
相当简单。每个传入的信息会显示在窗口上,然后循环等待下一条信息的传入。

—————————————————————————————————————————————————————————————————————————

局限

现在,我们有一个完整,尽管很简约,多线程的聊天室系统。怎么可能出错呢?


正如我们在介绍中提到的一样,没有服务端框架对于所有任务是平等的。知道这种方法的局限性是很重要的,你会决定是否你会应用这些想法在你自己的项目中去。

—————————————————————————————————————————————————————————————————————————

简化连接模型

我们创建的聊天室系统仅仅是一个聊天室。记住每个信息会传入服务器然后发送给每个客户端。这个是不满足现实世界的要求的,不仅是由于显示时间的用户想要单独的聊天室,而且带宽的极大浪费。


当然,在我们的模型中允许用户选择一个聊天室,然后根据房间名字连接每个信息,这样信息只会发送给相同房间里面的用户。


然而,我们没有为这个选择设置地方。我们的服务端线程对象简单地调用我们服务端对象方法sendToAll()。在真实世界里,服务端线程会分发信息给真实的分发系统。

—————————————————————————————————————————————————————————————————————————

过多的线程

在一些Java实现中,为每个用户创建显示不是一个好主意,因为有过多的线程 -- 即使它们全部休眠 -- 也可以让系统死掉。


这是你需要测试的地方,因为没有尝试就预料线程性能是不可能的。而且也证明了Java实现不能处理它,这个解决方案很危险。

这种情况下,你不得不用一种小、但是会从sockets读取一定数量的线程,你不得不使用不阻塞的线程,也就是意味着你不得不使用轮训,那就意味着……等等。这是一个大麻烦,如果你的JVM不能处理需多线程,打电话给你的供应商抱怨他吧!

—————————————————————————————————————————————————————————————————————————

内部同步

在Server.java中注释的代码提到一些线程同步经常用于适当保持活跃连接列表。这种同步真的可以影响性能。


如果同步证明是一个瓶颈,那么你可以试试下面的事情:

  • 修改removeConnection(),简化移除链接的记录,获取在另一个列表中。然后遍历中或遍历后,在sendToAll()中真正移除的动作。
  • 使用不止一个线程写入sendToAll().

—————————————————————————————————————————————————————————————————————————

结束语

本编教程涉及了Java语言中大量细节使用在多线程的构造函数中,面向对象的服务端。你已经学会怎样一次处理多个客户端,而且你也知道了7大功能点组成了这样的服务器。

参考文献

[1]. Building  a Java chart server

[2]. Java sockets 101以及中文系列 JAVA套接字(Socket)101

[3]. Java socket通信基本原理介绍

[Java聊天室服务器]实战之八 读写循环(客户端),,

[Java聊天室服务器]实战之八 读写循环(客户端)


推荐阅读
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 初探性能优化:入门指南与实践技巧
    在编程领域,常有“尚未精通编码便急于优化”的声音。为了从性能优化的角度提升代码质量,本文将带领读者初步探索性能优化的基本概念与实践技巧。即使程序看似运行良好,数据处理效率仍有待提高,通过系统学习性能优化,能够帮助开发者编写更加高效、稳定的代码。文章不仅介绍了性能优化的基础知识,还提供了实用的调优方法和工具,帮助读者在实际项目中应用这些技术。 ... [详细]
  • ZooKeeper 入门指南
    本文将详细介绍ZooKeeper的工作机制、特点、数据结构以及常见的应用场景,包括统一命名服务、统一配置管理、统一集群管理、服务器动态上下线和软负载均衡。 ... [详细]
  • 本文详细介绍了如何解决DNS服务器配置转发无法解析的问题,包括编辑主配置文件和重启域名服务的具体步骤。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 解决Parallels Desktop错误15265的方法
    本文详细介绍了在使用Parallels Desktop时遇到错误15265的多种解决方案,包括检查网络连接、关闭代理服务器和修改主机文件等步骤。 ... [详细]
  • 解决 Windows Server 2016 网络连接问题
    本文详细介绍了如何解决 Windows Server 2016 在使用无线网络 (WLAN) 和有线网络 (以太网) 时遇到的连接问题。包括添加必要的功能和安装正确的驱动程序。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 如何撰写初级和高级前端开发者的专业简历
    如何撰写初级和高级前端开发者的专业简历 ... [详细]
  • 该问题可能由守护进程配置不当引起,例如未识别的JVM选项或内存分配不足。建议检查并调整JVM参数,确保为对象堆预留足够的内存空间(至少1572864KB)。此外,还可以优化应用程序的内存使用,减少不必要的内存消耗。 ... [详细]
  • C++ 开发实战:实用技巧与经验分享
    C++ 开发实战:实用技巧与经验分享 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 为了在Fragment中直接调用Activity的方法,可以通过定义一个接口并让Activity实现该接口来实现。具体步骤包括:首先在Fragment中声明一个接口,并在Activity中实现该接口。接着,在Fragment中通过类型转换检查Activity是否实现了该接口,如果实现了则调用相应的方法。这种方法不仅提高了代码的解耦性,还增强了模块间的通信效率。此外,还可以通过ViewModel或LiveData等现代Android架构组件进一步优化这一过程,以实现更加高效和可靠的通信机制。 ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
  • CentOS 7 中 iptables 过滤表实例与 NAT 表应用详解
    在 CentOS 7 系统中,iptables 的过滤表和 NAT 表具有重要的应用价值。本文通过具体实例详细介绍了如何配置 iptables 的过滤表,包括编写脚本文件 `/usr/local/sbin/iptables.sh`,并使用 `iptables -F` 清空现有规则。此外,还深入探讨了 NAT 表的配置方法,帮助读者更好地理解和应用这些网络防火墙技术。 ... [详细]
author-avatar
七彩咩_131
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有