精华内容
下载资源
问答
  • java实现即时通讯软件

    千次阅读 多人点赞 2021-01-06 22:49:22
    导读:即时通讯软件即所谓的聊天工具,其主要用途是用于文字信息的传递与文件传输。使用eclipse作为即时通讯软件的开发工具,使用Socket建立通讯渠道,多线程实现多台计算机同时进行信息的传递,swing技术等进行实际...

    导读:即时通讯软件即所谓的聊天工具,其主要用途是用于文字信息的传递与文件传输。使用eclipse作为即时通讯软件的开发工具,使用Socket建立通讯渠道,多线程实现多台计算机同时进行信息的传递,swing技术等进行实际开发相对比较合适。通过一些轻松的注册登录后,在局域网中即时聊天便可以成功进行。

     

    目录

     

    项目结构:

     项目截图:

    总结:

    下载地址:


    项目结构:

     项目截图:

     

    总结:

    随着信息社会的快速发展,网络作为改变世界的最重要的因素。众多的企业纷纷使用局域网聊天来满足工作与交流高效、快速执行的需求。企业中使用内部局域网可以使内部信息交互的过程得以简化,从而达到提高工作效率的目的。所以经上所述,公司内部使用即时通讯的方式在各台计算机之间进行交流已经是时代发展的趋势。

    即时通讯软件即所谓的聊天工具,作为进行文字传输、文件传输的工具被使用在互联网的客户端上。从专业角度来介绍,即时通讯软件一般分为依赖于服务器的与依赖于P2P的。

    从现状来看,互联网上深受用户喜爱的即时通讯软件主要有以下几个:微信、QQ、YY、飞秋等等。

    如今的社会是信息社会,正是因为用户大量的需求促进了即时通讯的开发,信息快速的传递越来越受到重视同时使得互联网技术越来越成熟,在其中即时通讯软件承担了相当一部分的作用,在这些软件中,一些优秀且易用的聊天工具被各位用户所喜爱[3]。在中国,腾讯QQ无疑取得了极大的成功,简单易用,功能齐全,在满足用户基本需求的同时为各位用户提供其它使人称心的功能。即时通讯软件之所以能够取得成功,正是因为其适应了时代,符合了信息时代用户的需求,它不仅可以提供全面,大量信息给用户,同时也可以使用户的生活更加的精彩,成功满足了自身商业利益的获取也构建了人们和谐便利的生活。

    Socket是即时通讯系统实现的核心技术,可以通过端口设置与IP地址来构建通讯的桥梁,以便各类信息的发送与接收。在这个软件中可以与陌生用户或者你已加入用户列表中的用户进行信息的传递来完成基本的交流,系统在后续中是会继续进行功能的完善与拓展,来实现文件传输,语音传输等各种方式来加强用户的体验,为用户带来极大的便利。

    目前即时通讯系统的实现,为了资源的节约,是模仿过其他聊天软件的,在本系统中主要组成部分包含:账号的申请与通过账号进入聊天界面,陌生人到好友的添加,已加好友的删除,好友与好友,与陌生人的信息传递,这些简单易用的小功能确给用户带来了极大的便利,和优秀的用户体验,从而造就一个实用的软件。

    该即时通讯系统可以在很大程度上确保信息的快速性与准确性,而且各种来往的信息传递,都将被存入相关的文件中,以便对其进行相应的管理与维护,在信息发生疏漏与不可避免的一些错误是,进行后期的维护与纠正是极为便利的,是很任性化,所以系统的整体体验是比较优秀的。

    软件已经完成即时聊天系统的基本功能,但是却不是很完善,界面在制作过程中花费不少精力,但仍旧不是很美观,所以在后续仍可以对其进行大量的优化,使其趋于完善,在开发本软件时,发现很多的知识已经比较模糊,所以在这个过程中又将以往所学重温一遍,深感收货颇丰。在开发过程中发现自己并不能很好将以往所学的各种知识融入到其中,所以在后续的学习过程中,还必须多多实践。

    下载地址:

    点我下载

    展开全文
  • 今天,在这篇文章中,我将介绍一款我自主开发的即时通讯软件flamingo(中文:火烈鸟),并开源其服务器和pc客户端代码。以此来对前几篇文章中说到的理论进行实践。 代码在github和csdn.net上各上传了一份: ...

            在我的《服务器端编程心得》这个系列的第一篇至第六篇都是讲了一些零散的不成体系的网络编程细节。今天,在这篇文章中,我将介绍一款我自主开发的即时通讯软件flamingo(中文:火烈鸟),并开源其服务器和pc客户端代码。以此来对前几篇文章中说到的理论进行实践。

           代码在github和码云上各上传了一份:

    github地址:https://github.com/baloonwj/flamingo

    码云:https://gitee.com/balloonwj/flamingo

    csdn上代码可能不是最新的,但是github上的代码是不断维护的,包括一些新功能的增加和bug的修复。如果你想关注flamingo的最新功能,请关注github上的更新。如果你只想研究下网络通信程序的基本原理和编码技巧,csdn上的代码就足够了。

     

    目前即时通讯软件实现了如下功能(这里只列举网络相关的功能,其他客户端已经实现的功能不统计在列,请自行发现):

    • 注册
    • 登录
    • 查找好友、查找群
    • 添加好友、添加群
    • 好友列表、群列表、最近会话
    • 单人聊天功能(包括发文字、表情、窗口抖动、离线文件)
    • 群聊功能(包括发文字、表情)
    • 修改密码
    • 修改个人信息(自定义昵称、签名、个性头像等个人信息)
    • 自动升级功能

     

    下面是pc版本的一些截图:

    下面是安卓版本的一些截图:

    客户端还有很多细节功能,比如头像有三种显示模式、好友上线动画、聊天记录、聊天自动回复功能等,有兴趣的同学可以自己探索尝试一下吧,这里就不截图了。

    服务器代码编译与运行环境

    flamingo服务器端代码使用cmake + makefile编译,使用了纯C++11开发,运行于linux系统下(我的系统是CentOS7.0),为了支持C++11,你的gcc版本至少要大于4.7,我的版本是4.8.5。另外,使用了mysql数据库,我的数据库版本是5.7.17。我实际安装的是mysql的开源分支mariadb,安装方法如下:

    [root@yl-web yl]# yum install mariadb-server mariadb mariadb-devel

    mariadb数据库的相关命令是:

    systemctl start mariadb  #启动MariaDB
    
    systemctl stop mariadb  #停止MariaDB
    
    systemctl restart mariadb  #重启MariaDB
    
    systemctl enable mariadb  #设置开机启动

    所以先启动数据库

    [root@yl-web yl]# systemctl start mariadb

    然后就可以正常使用mysql了:

    [root@yl-web yl]# mysql -u root -p
    Enter password: 
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MariaDB connection id is 3
    Server version: 5.5.41-MariaDB MariaDB Server
    
    Copyright (c) 2000, 2014, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MariaDB [(none)]> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | test               |
    +--------------------+
    4 rows in set (0.00 sec)
    
    MariaDB [(none)]> 

     

    注意:如果你使用的是低版本的CentOS系统,或者其他版本的linux系统,你安装的mysql不是mariadb的话,需要安装的分别是:mysql-server mysql 和mysql-devel。

    服务器代码不仅是一款即时通讯软件的服务器代码,同时也是一款通用的C++11服务器框架。

    服务器代码使用方法:

    编译方法

    1. 进入程序目录,输入cmake . (注意有一个点号,表示当前目录)

    2. 没有错误,输入make

    3.最终会产生三个可执行程序:

    聊天服务器 chatserver

    文件服务器 filesever

    图片服务器 imgserver

    编译完成。

    部署方法:

    说明:

    在配置文件中etc/chatserver.conf中,配置的mysql数据库的用户名为root,密码为123456,请根据你自己的需要修改相应的用户名和密码。

    chatserver是聊天服务器,fileserver是文件服务器,文件服务器负责上传和下载聊天中发送的文件,imgserver负责上传和下载聊天中的图片。三个服务相互独立,互不影响。聊天服务器监听端口是20000,文件服务器端口是20001,图片服务器端口号是20002,这三个端口供客户端连接,其中聊天端口和客户端是长连接,文件端口和图片可选择长连接或短连接。

           第一次运行chatserver时,如果能顺利连上mysql,chatserver会自动检测是否存在名为flamingo的数据库,如果不存在则创建之,并新建三张信息表,分别是用户信息表:t_user, 好友关系表t_user_relationship和聊天消息记录表t_chatmsg。第一次启动fileserver时会创建filecache目录,这个目录用来存储聊天中的离线文件以及客户端升级包。第一次启动imgserver时,会创建imgcache目录,这个用于存储聊天过程中的聊天图片和用户头像文件。

    为了方便查看代码,我用Visual Studio来管理代码,可使用VS打开myserver.sln查看和管理代码。(VS版本必须是VS2013或以上版本)

    pc客户端代码使用方法

    编译:

    1.用VS2013打开程序目录下的:Flamingo.sln,你可以使用其他的VS版本,但是至少不低于VS2013,因为客户端代码也使用了大量C++11语法和库,VS2013及以上版本才能较好的支持C++11的语法。

    2. 打开的解决方案包括三个项目:Flamingo是即时通讯主程序,CatchScreen是聊天中使用的截图工具,iUpdateAuto是升级功能中用到的解压工具。

    3. 用VS2013编译整个解决方法即可,编译成功以后将在Bin目录下生成对应的程序。启动Flamingo.exe注册一个账号就可以开始使用flamingo了。

     

    Android客户端编译方法

    使用Android Studio打开对应的flamingo安卓项目编译,生成apk文件安装到手机上即可使用。

     

    如果你暂时不想研究服务器代码,但又想使用客户端,你可以连接我的测试服务器,测试服务器地址是:

    聊天服务器地址:101.37.25.166 端口号:20000

    文件服务器地址:101.37.25.166 端口号:20001

    图片服务器地址:101.37.25.166 端口号:20002

    你可以在登录界面的网络设置里面进行设置(登录界面右上角最小化按钮左边的一个按钮)。

    如果测试服务器无法访问,请加我微信 easy_coder 联系解决。

        这篇文章暂且就这样了吧,如果有您对我的程序有任何意见或者建议,或者有不错的想法欢迎与我交流或者给我留言(QQ:906106643).。代码中也有些“拿来主义”,另外程序中使用的图片和图标来源于网络,仅供用于学习,请勿用于商业用途,如果不小心侵犯了您的版权,请联系我。

       接下来的几篇文章,我会详细地介绍这款即时通讯软件服务器端与客户端代码的框架结构和实现细节。敬请期待。

       当然,我保证,我会持续维护flamingo,让这款软件越来越好,欢迎关注github上的更新:

    https://github.com/baloonwj/flamingo

    如果你有任何问题可以在博客或者github问题页面留言(https://github.com/baloonwj/flamingo/issues),我看到会尽量回复你的。

           

           欢迎加入 QQ 群:729995516,进行技术讨论与交流。

           更多服务器开发知识,欢迎关注『高性能服务器开发』公众号。

      

     

    展开全文
  • 类 QQ IM 通讯软件开发实战

    万次阅读 2018-07-03 02:45:09
    曾几何时,你是否也在梦想自己也能写出一个像 QQ 一样牛气的即时通讯软件?即使你不曾有过这个“野心”,你肯定也对 QQ 的实现原理感到好奇过,对吧?本达人课即将带您一探 QQ 此类 IM 软件背后的诸多实现细节。 此...

    课程简介

    用习惯了微信的你,还记得当初的 QQ 吗?曾几何时,你是否也在梦想自己也能写出一个像 QQ 一样牛气的即时通讯软件?即使你不曾有过这个“野心”,你肯定也对 QQ 的实现原理感到好奇过,对吧?本达人课即将带您一探 QQ 此类 IM 软件背后的诸多实现细节。

    此达人课涵盖了网络编程、设计模式、通信协议等基础知识,基于套接字(Socket)技术,实现了一个基于控制台的即时通讯软件(IM)。能够进行文本聊天、文件传送、发送表情等。支持服务器并发、内网穿透;当内网穿透失败时,允许服务器转发消息。

    通过实现这样一个简单的 IM 软件,帮助读者消除 Socket 编程过程中的误区和困惑,更加深入的理解 TCP/IP 协议原理。另外,在现在这个年头,不把“高并发”挂在嘴上,都不好意思开口说话。高并发确实有着一定的门槛,但也并不是高不可攀,只是需要我们付出努力去学习、去实践,要知道,经验非常重要。我们的这个 IM 软件涉及到内网穿透(NAT 穿透、“打洞”)、服务器并发、心跳包检测等,这些技术对于网络应用都十分重要,想要深入网络编程的同学千万不能错过。

    本达人课共包含以下四部分:

    第一部分(第01课),作为开篇,对本项目做了一个整体的介绍,并对 IM 开发需要用到的知识进行概述;

    第二部分(第02课),从基本原理层面,详细阐释了开发一个即时通讯软件需要理解和掌握的必备技能;

    第三部分(第03-07课),从代码层面,给出了本项目主要部分的具体程序实现,便于读者较好的了解细节;

    第四部分(第08课),作为总结,阐释了网络编程过程中常踩到的“坑”,希望能帮助读者在后续的 Socket 开发生涯中,少走一些弯路。

    主要涵盖的技术点有:

    • Socket 编程
    • 服务端并发
    • 同步/异步、阻塞/非阻塞等 I/O 模型
    • 内网穿透及 P2P 通信
    • 心跳包检测机制
    • 应用层通信协议设计
    • TCP/IP 协议栈原理

    作者介绍

    汪磊,自由开发者,CSDN 博客作者,毕业于211,九年老司机。错上贼船已悟道,遂深耕于后端,前端略懂皮毛。丰富的项目经验,用代码诠释世界。

    课程内容

    导读:功能概览

    引言

    用习惯了微信的你,还记得当初的 QQ 吗?曾几何时,你是否也在梦想自己也能写出一个像 QQ 一样牛掰的即时通讯软件?即使你不曾有过这个“野心”,你肯定也对 QQ 的实现原理感到好奇过,对吧?有人可能会说,“我从来没有好奇过”,好吧,我承认,你的这个回答只能说明两种可能,你是大神,或者你根本不是程序员!

    记得当初我还是一个“懵懂少年”的时候,用 .NET 的 Remoting 技术写了一个及其丑陋的小聊天工具,知其然不知其所以然,踩了无数的坑,到最后不了了之。现在回想起来,总结为一句话,“基础不牢、地动山摇”。那时候,我对 TCP/IP、Socket 等一窍不通,正所谓“初生牛犊不怕虎”。

    后来,一个偶然的机会,我接触到了《HTTP 权威指南》一书,进而找到《TCP/IP 详解卷》这本“圣经”级读物,从而一发不可收拾,开始了对网络底层原理的探究历程。如今,已是而立之年,岁月洗去了身上的浮躁,懂得静下心来好好沉淀一下自己的知识体系。回首当初自己一个又一个的“作品”,尽管散发着青涩,却记载着我的青春。

    好了,瞎聊了这么多,我们言归正传吧。

    在网络极其发达的今天,无论是 PC 端软件,还是移动端 App,几乎都有联网功能。移动端诸如微信、支付宝、美团、京东及各种手游,PC 端诸如各种关系数据库(MySQL、MSSQL、Oracle)、高速缓存(Redis、Memcached)、网站及 Web 浏览器、QQ 及各种网游,都以网络通信为基础。甚至 Windows 下的远程桌面、网络邻居、共享文件夹以及使用 SSH 登录 Linux,本质上也是通过 Socket 进行的,只不过设计了各自的通信协议而已,有兴趣的朋友可以通过 Wireshark 等工具亲自进行抓包,看看其交互过程。再比如,就是我们平常上网用到的 Web 浏览器(比如 IE、360、搜狗等),只不过是利用 Socket 同 Web 服务器通过 HTTP 协议进行了一种“请求/响应”操作,浏览器向服务器发出对某个 URL 的请求,然后服务器发回 HTML 形式的响应,浏览器再对 HTML 进行解析渲染。其实仔细想想,上面列举的这些司空见惯的软件,说到底不就是一些 Socket 操作吗?

    然而,Socket 看似简单,但真正想把它用好却不简单,Socket 编程是出了名的“坑”多,相信有过 Socket 编程经历的朋友都有此感受。Socket 究竟是什么呢?说白了,它只不过是操作系统给开发人员提供的一个进行网络操作的接口,通过 Socket,我们可以和操作系统内核中的 TCP/IP 协议栈进行交互,从而实现网络信息的收发。这就涉及到 TCP/IP 协议族,这可是一个极度复杂的知识汪洋,值得你深入研究。

    本课以 C# 为语言平台,阐述了如何实现一个基于控制台的即时通信软件,也就是常说的 IM。透过即时通讯工具的表象,探究其背后的网络通信基本原理,澄清关于 Socket 操作的一些细节和常见误区,让读者对 TCP/IP 协议栈的实现原理及其应用有更为深刻的理解。

    另外,现在这个年头,不把“高并发”挂载嘴上,都不好意思开口说话。高并发确实有着一定的门槛,但也并不是高不可攀,只是需要我们付出努力去学习、去实践,要知道,经验非常重要。我们的这个 IM 软件涉及到内网穿透(NAT 穿透、“打洞”)、服务器并发、心跳包检测等,这些技术对于网络应用都是十分重要的,想要深入网络编程的同学千万不能错过。

    功能概览

    会当凌绝顶,一览众山小

    为了专注于业务功能的实现,避免 UI 逻辑分散我们的注意力,我们的这款 IM 软件采用 Windows 控制台的形式。项目总体上包括服务器和客户端两个相互独立的部分,是一个典型的 C/S 结构。见下面的图1和图2所示。

    怎么样,黑色背景配上绿色字体,很有科技感吧?有没有黑客帝国的感觉?呵呵!基于控制台实现的聊天程序在用户体验方面和窗口程序比起来显得比较 Low,不过基本原理是一样的,你完全可以写成 WinForm 形式。

    图1 IM 服务器

    client

    图2 IM客户端

    服务器端

    服务器作为各个客户端进行通信的枢纽及中介,主要作用包括:处理用户登录注册及退出等请求、维护用户信息、好友上线和下线通知、检测用户在线状态、辅助内网穿透以实现 P2P 通信、内网穿透失败情况下的消息中转、分发表情包等。

    服务器端启动以后,会监听来自各个客户端的连接请求(登录、注册、注销、请求好友信息、内网穿透协助等),并根据请求类型分别返回合适的响应(见图1)。当有用户上线或下线时,服务器端会监听到该动作,并通知该用户的所有好友,以更新相应客户端的好友列表。

    服务器的一个重要功能是,检测用户是否在线。有人会说了,这还不简单,客户端下线时向服务器发送一条消息,通知服务器“我要下线了”。没错,在客户端正常退出的情况下,这种方法行之有效,但如果客户端的下线是由于电脑死机、断网等突发事故造成的呢?客户端还来不及向服务器发送下线通知,就已经 Game Over 了。所以,服务器要采取合理策略,以应对客户端异常的连接中断。

    客户端

    对于一个 IM 软件来说,客户端是普通用户接触最多的,其核心作用当然就是好友之间的聊天了,当然还包括一些辅助功能,如:用户的注册登录及退出、添加好友、查看好友列表、传送文件等。

    在我们的 IM 中,双方只有互为好友才能聊天。客户端 A 可以向服务器 S 发出添加某个好友 B 的请求,服务器负责把该请求转达给好友 B,好友 B 同意后,二者即建立起好友关系。已登录的客户端可以从服务器获取自己的好友列表,以及哪些好友在线、哪些不在线。

    出于简单考虑,本系统目前只支持文本形式的聊天会话。至于语音聊天、视频聊天,基本原理是一样的,有兴趣的朋友可以自己加以实现。我们还实现了发送表情的功能,当然,这里的表情指的是字符图案,而不是大家平时用 QQ、微信之类的可视化表情,毕竟是控制台程序嘛,要求不要太高!此外,还实现了表情包在线更新功能,当客户端连接到服务器时,服务器会自动向客户端推送最新的表情包,之后客户端便可以使用最新的表情了。用户可以查阅自己和其他好友的聊天记录,至于聊天记录是保存在客户端本地,还是保存在服务器,出于不同的考量,会有不同的策略。客户端之间可以以二进制形式互相传输文件,并且提供了哈希校验机制,以检查文件传输过程中的是否发生错误。

    提到 P2P,相信大家都不陌生吧?但究竟什么是 P2P 呢?

    P2P,即“点对点”,英文是“Peer to Peer”,意思是两个节点之间直接通信,不需要第三方充当中介进行中转。在一个 IM 系统中,用户之间的聊天信息有两种方式进行传递,一种是用户 A 把信息发送给服务器 S,服务器 S 再把该信息转发给用户 B(见图3);另一种就是我们这里所说的 P2P 方式,即用户 A 把信息直接发送给用户 B,而不用经过服务器 S(见图4)。

    无标题

    图3 服务器中转

    无标题2

    图4 P2P

    P2P 的优势显而易见,少一道工序、少一个步骤,效率必然比服务器中转要高。然而,由于 NAT 设备的存在,好多终端都没有合法的公网 IP,和这样的终端进行通信就需要“内网穿透”(就是指常说的“打洞”)。但是 NAT 技术尚未标准化,各种 NAT 设备的实现策略也没有统一,内网穿透不保证一定会成功,所以当内网穿透失败时,P2P 就不能实现了,还时需要服务器对消息进行中转。

    下面解释一下刚才提到的 NAT 技术。我们知道,当前32位的 IPv4 地址几乎已经耗尽,不可能给所有终端互联网用户都分配一个公网 IP,而互联网用户的数量又在不断增加,怎么办?于是就出现了所谓的 NAT 技术,简单来说,就是用一个 NAT 设备把一个公网 IP 提供给多个终端使用,使得多个电脑可以共用一个公网 IP 地址来上网。

    NAT 设备一般都有一个特点,就是对外隐藏内网各个终端的真实 IP,内网的机器可以主动向外网发送信息,但外网不能主动向内网发送信息。这就给我们上面提到的 P2P 通信造成了很大的困难,因为我们不知道通信双方各自的真实 IP 地址;即使知道对方的 IP,也不能主动向对方发起通信,因为对方的 NAT 设备会拒绝。要想和 NAT 内的终端进行通信,就要想办法穿透 NAT 设备的壁垒,这就是所谓的内网穿透。

    刚才提到了“服务器中转”这个概念,我们知道,服务器中转给通信引入了一道额外的步骤,本来双方之间可以通信的,非要另找一个人来传话,不但有可能传错话,当客户端较多时,服务器这个中间人的工作量就会很重,容易成为性能瓶颈。当然了,内网穿透失败,或者出于监视用户间通信的需要,仍然要用服务器来中转。

    第01课:Socket 通讯基本原理

    任何网络应用的实现都离不开 Socket 编程,当然,你也可以使用更高层次的抽象与封装,诸如 TcpListener、TcpClient、UdpClient,以及更加抽象的 WCF、WebService、Remoting 等技术。然而,要想更为深刻的理解网络通信的底层原理,最终还是绕不开套接字(Socket)。

    只要对 Socket 编程稍有了解,就会知道诸如 Bind、Listen、Accept、Connect、Send、Receive 之类的操作,确实,所有的网络应用就是这些基本操作的合理使用。对于 TCP 而言,由于它是面向连接的协议,一般就需要一方充当服务器的角色进行监听、另一方充当客户端发起到服务器的主动连接。使用套接字进行 TCP 编程的一般用法如下。

    服务器端代码:

    Socket tcpListenSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);var tcpLocalEnd = new IPEndPoint(IPAddress.Any, listenPort);tcpListenSock.Bind(tcpLocalEnd);tcpListenSock.Listen(10);while(true){var workerSock = tcpListenSock.Accept();byte[] buf = new byte[1000];workerSock.Receive(buf);}

    代码段1

    客户端代码:

    Socket serverSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);serverSock.Connect(serverEndPoint);byte[] buf = new byte[1000];serverSock.Send(buf);

    代码段2

    上面代码的大致流程是:服务器监听连接、当有客户端连接时,服务器接收该连接,并开始接收客户端发送过来的数据并对其进行处理;客户端向服务器发起连接请求,连接成功后,向服务器发送数据。

    网上好多关于 Socket 编程的教程大都一上来就介绍上面的这种操作,导致好多初学者在头脑里认为 Socket 编程就应该是这样的。甚至很多初学者会以为服务器只能接收数据、客户端只能发送数据,客户端要想接收服务器发送的数据,先要在客户端的某个端口上监听来自服务器的连接(见图1)。他们只知道TCP是全双工的协议,却仅仅停留在知道这个概念而已,和实际应用联系不起来。

    x

    图1 错误的思路

    代码段1和代码段2只是说明了最最基本的 Socket 编程方式,用术语来说就是“交互式同步阻塞 I/O”。在这种方式中,服务器监听本地端口,当没有连接请求时,用户进程会阻塞在 Accept 函数,直到有客户端请求连接;另外,当有某个客户端连接传入后,服务器用户进程就会忙碌于接收客户端数据的工作,如果此时有新的客户端连接过来,服务器就不能进行响应。这种方式之所以称为“交互式”,就是因为类似于“客户端问一句、服务器答一句”的形式。

    当然了,通过百度还可以找到如下代码示例:

    while (true){    var workerSock = tcpListenSock.Accept();    var remoteEnd = workerSock.RemoteEndPoint as IPEndPoint;    ThreadPool.QueueUserWorkItem(obj =>    {       while (true)       {          byte[] buf = new byte[1000];          int r= workerSock.Receive(buf);          if (r<=)             break;       }    });}

    这种方式比刚才那种“交互式同步阻塞 I/O”要好一些,借助于线程池技术,在一些并发不高的简单场合完全可以适用。该方案用一个单独的线程来处理已经建立的连接,使得主线程能够继续监听其他客户端请求。但这种方式要求为每一个客户端连接都开辟一个单独的线程,在少量客户端连入的时候没有什么问题,但如果有成千上万的并发请求传入时,系统就要分配成千上万的线程来应对每一个连接,很显然,这种方案不能应对高并发。在生产环境中,应对高并发绝不是只用一台服务器来实现的,通常是一个服务器集群,采用负载均衡技术来给各个服务器分配任务。对于每一台服务器,还要采用诸如非阻塞、多路复用甚至异步 I/O 等模式,这都是较为高阶的网络编程技术,需要在实际工作中积累经验。

    面向连接的 TCP

    由于服务器需要保存客户端登录、会话以及活动的各种状态,客户端和服务器之间的通信采用面向连接的 TCP 协议。另外,不像传统的 HTTP 服务器和浏览器之间采用短连接(现在的 HTTP 协议默认使用长连接),我们在这里连接采用长连接,也就是说,一旦客户端和服务器建立 TCP 连接后,不会自动断开连接,而是一直使用该连接传输数据,直到客户端主动断开连接为止。

    用户注册、登录与注销

    在服务器已经运行的前提下,客户端启动后,会主动向服务器发起 TCP 连接请求,服务器一旦接受连接请求,二者之间就成功建立起一条 TCP 连接。客户端使用该连接向服务器发送注册、登录与注销的请求报文,服务器同样用这条连接向客户端发回相应的响应报文。

    服务器监测客户端在线状态(心跳包)

    一种常用的策略是服务器和客户端之间维持一个“心跳包”通信,顾名思义,“心跳包”就是以某一频率在服务器和客户端之间传送的微型报文。就像心跳一样,有心跳就说明客户端和服务器之间的连接还存在,没有心跳就说明二者之间的连接 Over 了。这样,即使客户端由于停电、死机等突发状况,来不及向服务器报告下线通知,服务器也能够检测到该客户端已经不在线了。

    服务器分发用户好友地址

    某个用户成功登录后,应该能够获取该用户的好友列表,并且能够给某个好友发送消息,这是 IM 应该具有的基本功能。上文中提到,用户 A 向好友 B 发送消息,既可以通过服务器进行中转,也可以用 P2P 方式进行直接通信。无论是哪种方式,都要知道 B 的 IP 地址,那么 B 的 IP 地址从哪里获得呢?我们知道,当用户 B 登录服务器时,会与服务器建立一条 TCP 连接,此时服务器肯定知道 B 的 IP。所以,服务器需要在 B 登录时,保存好用户 B 的 IP 地址,并向 B 的所有好友(包括 A)分发 B 的 IP 地址信息。

    内网穿透失败时转发用户之间的通信

    虽然 P2P 通信效率较高且不会给服务器造成太大压力,但存在通信失败的可能。大家想一下我们家里上网用到的宽带路由器,它其实就是一个交换机和带有 NAT 功能的路由器的集合体(见图2),它负责把我们家里各个终端设备的内网IP转换成公网IP。要想实现P2P就要穿透这些NAT设备,就是所谓的“打洞”。虽然说用“打洞”技术可能实现内网穿透,但NAT技术还没有标准化,不同的NAT设备各自的具体实现机制不一样,不能保证所有的内网都能被穿透。这种情况下,就需要借助服务器来转发用户之间的消息。

    NAT

    图2 家用宽带路由器示意

    传送文件

    实现文件传送,既可以使用 TCP 协议,也可以使用 UDP 协议。有的人更偏好于 UDP,认为 UDP 协议简单轻量、网络负载低,就连 QQ 也是采用 UDP。不可否认,UDP 以“尽最大努力传输”为宗旨,没有 TCP 那样复杂的机制。但我们也要意识到 UDP 是不可靠的,要想实现可靠的端到端传输,需要应用层协议来实现诸如超时重传、流量及拥塞控制等机制,而 TCP 恰恰具备这些功能。也许有人会说,我自己实现重传、流控等机制不就行了么?你当然可以自己做这些,但这些功能是相当复杂的,需要你有十分丰富的网络编程及协议开发经验,而且你自己写的不一定有 TCP 高效。另外,TCP 不像你想象的那样重量级,除非你需要实现广播,或者对实时性有较高要求(在线播放音视频),否则完全可以放心的使用 TCP。

    无连接的 UDP

    刚才说到 TCP 和 UDP 之间的抉择问题,确实需要因地制宜。TCP 的优势是稳定可靠,UDP 的优势是无连接、轻量级。IM 好友之间的普通文本聊天不需要建立持久的连接,因为一个用户在发送一条消息后,不知道下一条消息会在什么时候发送,所以没有必要用一条连接来为这种通信服务。此时,就可以采用无连接的 UDP,一个用户想说话时就发送一条 UDP 报文,不用关心对方什么时候回复,甚至即使一条两条消息丢失也不是什么大问题。当然了,如果你是完美主义者,你也可以在应用层加上一些简单的丢失重传机制。另外,由于 UDP 无连接的特性,它在实现内网穿透方面要比 TCP 方便一些。

    P2P 聊天

    在服务器的帮助下,用户 A 可以得到好友 B 的 IP 地址,从而可以用 UDP 直接向好友 B 发送聊天报文,好友 B 在本地指定的 UDP 端口上接收相应的报文即可。当然,实现 P2P 通信的前提是通信双方都有合法的互联网 IP 地址,倘若一方或双方位于 NAT 设备的内网,用普通的方法就不能实现通信了,因为双方不知道对方的公网 IP 地址。此时,就需要内网穿透了。

    内网(NAT)穿透

    在前面多次提到“内网穿透”,俗称“打洞”,这个概念听起来是不是显得非常“高大上”?其实,所谓的“NAT 穿透”、“内网穿透”、“打洞”都指的是一个概念,只是叫法不同而已。我们都知道,内网穿透的目的是,使得位于内网的两个终端能够直接进行通信,避免服务器作为第三方中转。那么内网穿透该怎么实现呢?

    其实内网穿透的基本原理并不复杂,前提是想办法得到 P2P 双方的公网 IP 地址,关键是找出内网终端经过 NAT 转换后的通信端口。这里我们主要介绍的是 UDP 穿透,图3中的 A 和 B 是两个位于各自内网中的电脑终端,NAT_ANAT_B 分别是 A 和 B 的网关,各自的 IP 地址及端口都已经标明。

    UdpPunching

    图7 UDP 穿透示意图

    获取通信双方的公网 IP 并不困难。我们知道,网络上的两台电脑要想相互通信,就必须要知道对方的 IP 地址及其端口号。由于电脑 A 和 B 都分别位于各自的内网中,它们都不具有合法的公网 IP 地址,所以二者不能直接通信。但是,A 可以和 NAT_B 的外网接口通信,B 也可以和 NAT_A 的外网接口通信,而 NAT_ANAT_B 外网接口的 IP 地址就是 A 和 B 经过 NAT 转换后的外网IP。也就是说,A、B 要想通信,先要获取对方的外网 IP 地址,具体方法是:A 和 B 都和服务器建立 TCP 连接,这样服务器就知道 A 和 B 各自的公网 IP,然后服务器把各自的公网 IP 通过 TCP 连接告诉对方即可。

    难在如何获取 NAT 后的外网端口。要想弄明白内网穿透的实现细节,就要搞明白 NAT 设备如何把内网地址转换成公网地址。前面我们多次提到,NAT 技术还没有标准化,也就是说,不同厂家的 NAT 设备,内外网地址转换的实现方法也不一样。在有的 NAT 设备实现中,只要内网终端的 IP 和端口不变,不管访问公网的哪台服务器,转换成的外网端口也保持不变;而对于有的 NAT 设备,即使是相同的内网 IP 和端口,只要访问的外网服务器不同,转换成的外网端口也不同。有的 NAT 设备允许数据包从外网自由的进入到内网,而大多数 NAT 设备不允许不请自来的外部数据包进入。所以说,实现内网穿透的关键是找到内网主机被 NAT 设备所映射成的外网端口号。

    正因为不同的 NAT 设备转换的外网端口不一定能得到,所以内网穿透不一定能成功。大家回想一下在使用 QQ 聊天的时候,有没有遇到过系统提示“服务器中转”?这就是由于内网穿透失败,QQ 服务器把聊天内容进行了中转。

    最容易实现穿透的是同一内网 IP 和端口被 NAT 转换后的外网端口保持不变的 NAT 设备。如图3所示,A 通过 NAT_A 向服务器发送报文,经 NAT 转换后的端口号是6001;A 通过 NAT_ANAT_B 发送报文,经 NAT 转换后的端口号也是6001。这种情况下,在通过服务器得知对方的公网 IP 和端口以后,A 向 B 发送一条报文的步骤如下:

    1. A 先告诉服务器,“我要给 B 发送一条报文”;
    2. 服务器给 B 发一个命令,让 B 向 A 的公网端口6001发送一条报文 Dr_BA
    3. 报文 Dr_BA 发出后,B 通知服务器,“我已经向 A 发报文了”,然后服务器把该消息转告给 A;
    4. A 向 B 的公网端口8001发送一条报文 Dr_AB

    我们知道,NAT 设备不允许不请自来的外部报文进入,于是报文 Dr_BA 会被 NAT_A 丢弃;但是报文 Dr_BA 会在 NAT_B 上留下一个映射记录,就相当于在 NAT_B 设备上打了一个“洞”,以后由外部发送到端口8001的报文就能够通过这个“洞”进入 NAT_B 内部网络,这样 A 到 B 的通信就成功了。

    第02课:程序骨架之服务端

    我们这款 IM 包括服务器和客户端两部分,其中,服务器负责各个客户端之间的联络,以及服务器和客户端之间的交互;客户端就是我们终端用户接触到的聊天软件。

    任何复杂的软件系统也不是一下子就凭空拔地而起的,总是由一些核心代码慢慢扩充而来,聊天软件的核心代码很简单,无非是服务器监听、客户端连接,以及客户端之间的通信而已。

    上文讲基本原理的时候,列举了两段代码(代码段1和2),这两段代码其实就构成了服务器和客户端之间通信的核心代码。我们在这里使用的是最基础的 Windows 套接字(Socket),虽然用起来比 TCPListener、TCPClient 之类的要麻烦一些,但能够使我们更清晰的了解网络编程的基本原理,以及获得更高的灵活度。

    Socket,直接翻译过来是“插座”的意思,术语俗称“套接字”。好多人对 Socket 到底是什么并没有一个清晰的概念,只知道它是用来操作网络通信的一个类。其实“插座”这个叫法还是比较形象的,它给我们提供了应用程序和操作系统内核中的 TCP/IP 协议栈软件之间的操作接口。图1用直观的形式说明了 Socket 在分层网络体系中的位置,由图可见 Socket 为我们在应用层和传输层及网络层之间搭建起了桥梁,借助 Socket,我们既可以操作 TCP/UDP 协议栈,又可以直接操作原始 IP 数据报。

    img

    图1 Socket 在分层网络体系中的位置

    服务器

    服务器和客户端之间的通信采用 TCP 协议。服务器负责监听客户端传入的连接,以及向客户端发送数据,一般过程是:

    1.服务器端建立一个监听 Socket,并且设置好地址族、套接字类型以及协议类型。由于 TCP 协议属于基于比特流的流式协议,所以我们把该套接字设置为 IPv4 地址族、流式套接字以及 TCP 协议。

    private Socket tcpListenSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    2.把监听 Socket 绑定到一个本地终结点,以后这个终结点收到的连接请求都由这个监听 Socket 处理。所谓终结点指的是 IP 地址和端口号,因为要想通过网络通信,网络层需要知道 IP 地址,传输层需要知道端口号。

    tcpLocalEnd = new IPEndPoint(IPAddress.Any, listenPort);tcpListenSock.Bind(tcpLocalEnd);

    需要注意的一点是,本地终结点中的 IP 地址我们指定为 IPAddress.Any,为的是能够监听本地计算机上所有网卡在端口 listenPort 上接收到的通信。虽然我们的电脑一般都只有一块网卡,但出于程序健壮性考虑,还是选择 IPAddress.Any。

    3.在监听 Socket 上调用 Listen 函数,使其开始侦听已绑定本地终结点上的连接。要知道,Listen 函数只有在 TCP 通信中才需要使用,UDP 不需要,因为 UDP 不需要建立连接。

    tcpListenSock.Listen(10);

    在导读中我说过,Socket 编程中“坑”很多,这里就有一个“坑”,上面代码中 Listen 函数的参数“10”是什么意思?是该套接字最大只允许建立10个连接吗?对于这个参数的意义,相信很多朋友都有误区。

    其实,这个参数的意思是,允许操作系统内核的 TCP/IP 协议栈为新传入的连接请求排入队列的最大个数。也就是说,如果应用进程来不及处理新传入的连接请求,协议栈会帮我们把超出应用进程处理能力之外的连接请求进行排队暂存,当应用进程有空时再从这个队列中取出新连接。这个队列的最大长度就是 Listen 函数的参数。

    如果我们的应用进程正在忙于处理某一次连接,无暇顾及新传入的连接,操作系统内核会帮我们把新传入的连接暂时保存到一个队列当中,最多保存10个新连接,当第11个新连接传入时,若应用程序还没有从队列中取走连接,则第11个新连接就会被丢弃。

    4.在监听 Socket 上调用 Accept 函数,准备接受一个新传入连接。

    var workerSock = tcpListenSock.Accept();

    如果没有新连接传入,Accept 函数会一直阻塞。当成功接受一个新连接后,Accept 函数返回一个新的 Socket,以后就可以用这个新的 Socket 来处理这条连接上的所有通信了。

    大家注意,“坑”又来了!这里澄清一个容易让人困惑的地方,就是 Accept 函数返回的新 Socket 和原来的监听 Socket 之间是什么关系?它们是相同的 Socket 吗?它们是绑定到了相同的本地终结点吗?难道多个 Socket 可以绑定到同一个端口?

    其实,Accept 函数返回的新 Socket 和原来的监听 Socket 是两个不同的 Socket,只不过他们俩绑定到了相同的本地终结点而已。既然它们绑定到了同一个本地端口,那么当网络上有数据来了以后,怎么区分数据是发给 Accept 函数返回的新 Socket,还是发给监听 Socket 呢?这是根据发送数据的远端终结点来决定的。

    再进一步解释之前,先铺垫一下关于 TCP 中“连接”的概念。一条 TCP 连接是由一个五元组定义的,即:协议、发送端 IP 地址、发送端端口号、接收端 IP 地址、接收端端口号)。只要这五个元素中有一个不同,就代表不同的连接。

    好了,继续刚才的叙述,见图2。每当Accept函数接受一个连接,协议栈都会把通信双方的五元组保存起来。当有后续数据发来时,检查一下远端终结点是否存在于本地保存的五元组记录当中。若不存在,则说明是新传入的连接(图5中的连接A),需要把数据发给监听Socket;若存在,则说明是在以前连接上传来的数据(图5中的连接B),需要把数据发给Accept函数返回的新Socket。

    img

    图2 监听 Socket 和 Accept 返回的 Socket 的关系

    5.服务器端用 Receive 函数接收数据。如果网络上没有数据传过来,则 Receive 函数会一直阻塞。若 Receive 函数成功返回,其返回值是此次从网络上读取到的字节数。

    byte[] buf = new byte[1000];workerSock.Receive(buf);

    Receive 函数的参数是你用来存储接收数据的缓冲区,一般是字节数组。初学者经常会为如何确定这个数组的大小感到困惑,甚至干脆设置一个非常大的数组。这又是一个“坑”,这样做是不科学的,会造成内存空间的无谓浪费。

    我们知道,TCP 协议是流式协议,报文之间不保留边界,不像 UDP 那样,每次接收到的数据都是一个完整的数据报。所以我们在接收数据时,只能按需读取合适长度的数据,也就是说,接收缓冲区数组的大小要根据你的应用层协议来确定,而不要简单粗暴的设置一个非常大的值。比如说,按照你自己制定的应用层协议,收到的数据中前4个字节代表发送端的用户名,那么你的接收缓冲区数组大小就设置为4;接下来的1个字节代表用户性别,那么第二次接收的缓冲区数组大小设置成1。

    6.如果服务器需要向客户端发回响应,则调用 Send 函数向客户端发送数据。如果协议栈的发送缓冲区已满,则 Send 函数会阻塞,直到协议栈发送缓冲区有空间。

    byte[] sendBuf = new byte[100];workerSock.Send(sendBuf);

    这里有两个比较容易造成混淆概念:应用程序缓冲区协议栈缓冲区,是 Socket 编程中一个较为高大上的“坑”。在使用 Socket 进行网络编程(尤其是 TCP)过程中,不可避免的要接触到缓冲区的概念。缓冲区有两类,一类是我们的应用层代码在使用 Receive 或 Send 函数收发数据时,提供给 Socket 的字节数组;另一类是操作系统内核中 TCP/IP 协议栈软件为在网络上收发数据及流量控制而设置的内核缓冲区。

    可以看下面这张图:

    img

    图3 关于各种缓冲区的示意

    图3中 ABCD 各部分的含义分别是:

    • A:应用程序的发送缓冲区。这个缓冲区是我们的应用程序代码在调用 Socket 的 Send 函数时提供的参数,即打算发送到网络的字节数组。

    • B:应用程序的接收缓冲区。这个缓冲区是我们的应用程序代码在调用 Socket 的 Receive 函数时提供的参数,即用来存放从网络接收到的数据的字节数组空间。

    • C:协议栈的发送缓冲区我们在调用 Socket 的 Send 函数并返回时,并不代表已经把数据发了出去,只是意味着把用户数据拷贝到了操作系统内核的协议栈缓冲区中,也即是 C。之后,TCP/IP 协议栈软件再从内核缓冲区中取出数据,并发送到网络。如果我们在调用 Socket 的 Send 函数时,内核缓冲区满了,那么 Send 函数就会阻塞,一直到内核缓冲区有空间为止。

    • D:协议栈的接收缓冲区我们在调用 Socket 的 Receive 函数时,并不是直接从网络上读取数据,而是从内核的一个缓冲区中读取数据,也即是 D。协议栈在收到网络上传来的数据时,会先把这些数据存放在内核缓冲区中,等待应用程序代码来读取。

    有人会问了,如果内核接收缓冲区满了怎么办?会丢失数据么?大家别忘了我们用的 TCP 协议,它是面向连接的可靠的流协议,在内核接收缓冲区满了的情况下,接收端会向发送端发送一个窗口通告,告诉发送端,“你先别发数据了,我没有地方存了,等我有地方了以后再告诉你!”,这就是 TCP 的流量控制机制。

    如果内核接收缓冲区为空,那么 Receive 函数会阻塞,直到缓冲区有数据为止。

    这里还有一个容易踩到的“坑”。有人会抓狂了,怎么老有坑?没错,Socket 编程就是这样,基本操作谁都懂,但是具体使用起来,可以说是一个“坑”接着一个“坑”。很多初学者以为服务器只能接收来自客户端的数据,认为服务器要想向客户端发送数据,得需要客户端也在本地监听某个端口,等待服务器的连接。这是一个非常常见的误区,我见过不少新手写出过这样的代码。我们知道,TCP 是全双工的协议,只要通信双方建立起连接,双方就可以在两个方向上相互通信。也就是说,服务器在接受一个客户端的连接请求后,除了可以接收来自客户端的数据外,也可以向客户端发送数据。

    还有,服务器是应该先接收数据再发送数据、还是先发送数据再接收数据?一般我们习惯于先让服务器接收数据,然后再发送数据作为回送给客户端的响应。由于 TCP 是全双工的,其实完全可以在连接建立以后就向客户端发送数据。

    服务器端的主要工作有:监听客户端连接、接收报文并根据报文类型作相应处理;保存用户登录状态、用户信息及好友列表;向所有客户端发送心跳包,以检测客户端在线状态;响应客户端关于好友 IP 地址的请求,以实现 P2P 通信;作为公网服务器,辅助实现内网(NAT)穿透。

    第03课:程序骨架之客户端及协议设计
    第04课:具体实现之报文类与 TCP 操作类
    第05课:具体实现之服务器类与客户类
    第06课:具体实现之点对点、服务器并发与心跳包机制
    第07课:Socket 编程中容易踩的坑

    阅读全文: http://gitbook.cn/gitchat/column/5b077eeeb9f775446da64412

    展开全文
  • Qt制作局域网即时通讯软件

    千次阅读 多人点赞 2019-12-21 21:35:07
    Qt制作局域网即时通讯软件 利用Qt制作的局域网即时通信软件,可实现文本信息、表情包、图片、文档等的传输功能。界面风格模仿的Tim,所以本软件取名为Timi,tim的mini版本。 登录界面:使用之前做的登录界面,...

    Qt制作局域网即时通讯软件

           利用Qt制作的局域网即时通信软件,可实现文本信息、表情包、图片、文档等的传输功能。界面风格模仿的Tim,所以本软件取名为Timi,tim的mini版本。

    1. 登录界面:使用之前做的登录界面,后续修改。原因是没找到好的素材(不会美工),有会美工愿意提供素材的请联系。
    2. 文本信息发送:气泡效n果,文本信揭秘那息可自动换行,并且文本信息可选择/可复制。
    3. 发送图片功能:通过udp发送图片,增加图片浏览器,双击图片可以查看详细信息。
    4. 截图功能:可实现类似微信QQ等截图功能。
    5. 表情包功能:发送表情包,表情包下载于网络上的QQ表情包。
    6. 文件发送功能:实现文件传输功能,样式模仿微信样式,由选择文件可以看到。
    7. 软键盘:调用软键盘,实现中文/英文、数字和符号等输入功能。
    8. 上线/下线广播通知:实现上线/下线提示功能。
    9. 收到消息提示功能:接受到消息,在头像左上角显示红色提示信息。

     1、登录界面

          基本登录界面,登录有托盘提示信息,如下图右下角信息及托盘。



    2、主界面 

             主界面样式模仿Tim,实现无边框拖拽、放大、缩小、圆角、阴影、最大化、最小化、托盘等基本功能。

             主界面主要由标题栏、左侧通信录、右侧的在线/离线栏、信息显示窗口、输入工具栏、信息输入窗口等几部分组成。



     


     3、文本信息发送/接受

            之前有通过js+html实现过气泡聊天效果,样式确实不错,不过太占内存了,在此进行改良,通过绘制实现,其中遇到过很多坑,比如绘制好后如何实现自动换行,并且中文/英文/数字换行都可以;再比如绘制的信息如何选择,发送的信息可以复制;还有就是发送图片时发送的图片过大或过小如何显示;发送文件应该如何显示,发送文件时发送样式怎么好看;发送表情包及gif图片如何做到动画播放的效果等等。

             发送文本信息功能,样式为气泡效果,文本信息可以自动换行,文本信息可以选择及复制。

             无论中文/数字/字母/符号都可自动换行,自动换行写了好几天。根据窗口大小,聊天信息自适应大小。




    4、发送图片功能

           通过选择图片进行发送,并增加了图片浏览器功能,可以查看图片详细信息,并且可以打印、下载、放大、缩小、还原、文件位置等功能。

           同样也实现了图片拖拽或复制到编辑窗口,可以同时发送多个图片。

           期间遇到的问题是如何显示图片过大或过小的情况,根据文件大小进行缩放。图片浏览器也需要此功能,如果发送常规不是特别大的图片好显示,如果特别大就会出现问题,包括文件进行缩小、放大、还原。

           图片放大,超过图片浏览器大小,目前可以通过键盘上/下/左/右键可以移动,通过鼠标拖拽实现图片移动还未实现,后续会将此功能加上。




    5、截图功能

           常规截图功能,类似微信的功能(功能不全,后续会添加),包括截图后图片左右旋转、保存到本地、取消、和保存到剪切板,点击对勾后可以到处进行粘贴。

           微信截图功能还是比较完善的,包括再绘制、重新选择区域等效果。这些效果在之前写的电子白板画图软件中有介绍,后续会将这写功能加上。



    6、发送/接受表情包

           表情包源自于网络下载,可以看到发送背景为蓝色看到有白色边框,这不是bug就是素材不好,有好点的gif表情包方便时可以发给我一份。

           发送表情包主要解决的就是表情包选择框的显示/隐藏问题、表情包实现动画效果。



     


    7、发送/接受文件

           发送文件样式模仿的是微信,之前想过类似钉钉、QQ、Tim等,最终觉得微信的还是比较不错的,同时可以发送多个,样式和微信一样,这里没录制具体发送,可以翻看微信的。发现电脑版微信自带表情包是静图,之前都没发现。

           同时增加了查看文档详细信息功能,双击文件发送聊天信息,可以显示文档详细信息,单击文档图标跳转到文档具体位置,方便快速定位到文件位置。

           发送文件通过tcp实现,自测发送3g的大文件无压力,不过同时发送多个大文件无亲测。这里设计的不是特别好,会着重改进此处功能。还有就是发送文件进度条显示问题,获取发送进度容易,如何一个显示效果我还没想好,后续慢慢改进吧。



     



    8、软键盘

           软件盘的实现如下功能,之前博客也写到了,软键盘皮肤可以更改的,同样字符库可以选择google的。软键盘在嵌入式环境用的比较多,win环境下没什么卵用吧。

           输入框工具栏还有其他功能需增加暂时未想好,欢迎大家提供意见,让功能更加完善。



     9、上线/下线通知

            通讯录采用QQ样式 ,展现用户头像,用户名,ip地址。后续增加签名效果。这里的头像都是固定样式,暂时未实现用户自定义功能,最近在整理上传头像及编辑头像功能,像QQ那样进行头像图片裁剪的效果,实现后再更新此功能。

           通信录这里暂时隐藏了群聊功能,暂时还未想好群聊应该怎么展现,群聊样式该如何,想好后也会将此功能增加上。

            在上下线提示栏能可以看到,上线颜色为蓝色并标记为online,下线颜色为灰色并标记为offline。这个显示效果也是想了好久,主要是因为这里未采用服务器,未能实现离线发送,所以要体现出接受方的在线状态,借鉴的效果不多,可能有在右下加弹出窗口的效果,好像360弹出的广告一样,像我这种360都不安装的人,这效果肯定接受不了。有好点的效果欢迎大家提议,能提供美工素材更是感激不尽。

          上下线没有录制两台电脑实际视频,最多试过5台电脑上下线效果,实测没问题。欢迎下载使用,可亲测。



    10、收到消息提示功能

           实现了收到消息提示的功能,提示方式如下面所示。收到消息后会在头像的左上角标记红色圆点。同样接受不了360似的右下角弹广告,奈何也没想到更好的效果。提供素材吧。

          头像图片来自网络,不好看,奈何不会美工,欢迎提供好看点的头像。



    11、项目构建

            整个项目代码如下,可以根据命名看到每个模块的实现,整个项目未使用ui,所有界面效果都是通过代码painter 绘制实现。后续会将各个模块具体实现方法分享给大家。

            整个项目代码于2019年12月份每个不眠的深夜一行一行敲的。 


           下载地址:https://pan.baidu.com/s/1aqHBWd2a9MeTHgWLwnrPAw  密码:tb5v

           大家可下载使用,顺便将使用当中的建议/意见及Bug反馈给我,使软件更加完善。

           主界面有我的联系方式,或者在此留言也可以。

           有需要或者想做局域网即时通讯软件的可以联系我。

           整个软件是我自己设计和开发的,能力有限,如存在不妥之处,欢迎大佬们指正。如果觉得不错的就点个赞吧。

    展开全文
  • 这个软件是没得说的,支持开源,崇拜开源工作者,谁都知道开源即时通讯软件(Instant messaging,简称IM),目前比较普遍的即时通讯都具备这些基本功能,允许两人或多人通过互联网即时地相互发送文字消息、...
  • 常用的即时通讯软件有哪些

    千次阅读 2020-09-07 16:10:39
    QQ:QQ是腾讯公司开发的一款基于internet的即时通讯软件,腾讯qq支持在线聊天、视频通话、点对点断点续传文件、共享文件、自定义面板等多种功能 微信:微信是一种更快速的im,与传统的短信沟通方式相比,更加灵活、...
  • 即时通讯软件开发 需要用到什么技术
  • 1553B通讯软件设计BC客户端

    千次阅读 2015-11-03 13:16:24
    作为1553B总线通讯软件,软件主要目的就是控制总线控制器BC和远程终端RT之间的数据交换。 本实验所用的板卡为EXC—PCI/MCH-1,相关资料可在官网下载:http://www.mil-1553.com。
  • 局域网即时通讯软件的实现(类似飞鸽)

    千次下载 热门讨论 2010-04-07 13:31:23
    局域网即时通讯软件的实现。 功能类似飞鸽,但添加了对话框聊天功能,只支持文件传输,不支持文件夹传输。
  • java开源即时通讯软件服务端openfire源码构建本文使用最新的openfire主干代码为例,讲解了如何搭建一个openfire开源开发环境,正在实现自己写java聊天软件: 编译环境搭建 调试环境搭建 步骤列表 下载openfire源码 ...
  • 即时通讯软件设计

    千次阅读 2008-05-10 13:08:00
    即时通讯软件设计 作者:文深 2007-12-02 18:50:15 标签: 艺术赏析 即时通讯软件 设计
  • 开源即时通讯软件

    千次阅读 2013-05-02 21:56:49
    开源即时通讯软件   Powertalkbox http://baike.baidu.com/view/2881610.htm 免费开源的asp.net,即时通讯控件与大家分享 这是一款免费开源的控件,作者的初衷是为了让来到网站上的人流资源更好的被把握住. ...
  • 今天的当我走进家门时的即时通讯软件,我听了,立刻我的心里浮现出了一种酸酸的味道,我有一颗牙齿摇得很历害,没有声音,光感动而不熟悉,在最后一次努力很形而上学的即时通讯软件那种后,光熟悉而不感动,口水也...
  • 企业该如何正确选择即时通讯软件

    千次阅读 2016-06-20 14:49:21
    企业即时通讯工具是一种面向...那么选择一款适合自己企业使用的即时通讯软件需要考虑哪些因素呢? 一、使用费用 对企业来讲,投入与产出始终都是需要考虑的问题。目前市面上已有的企业即时通讯软件有免费的也
  • 即时通讯软件Empathy

    千次阅读 2009-12-03 09:59:00
    Empathy支持广泛,多种通信协议让沟通无限,直观简洁,联系人列表一目了然,全新亮点,语音和视频让沟通更直接,简单方便,历史会话任意搜索查看,Empathy之所以成功替代老牌的即时通讯软件PidGin,是因为Empathy站...
  • 企业在选择企业即时通讯软件时应该注意哪些问题? 除了腾讯通rtx,其他类似的
  • QT开发的即时通讯软件(基于TCP)

    千次阅读 2018-11-21 14:36:05
    这是本人在学习QT和计算机网络的时候自己开发的TCP网络通讯软件,包含服务端和客户端两个工程,亲测可用,我自己也经常用它们做网络的测试,注释详细,欢迎参考,先上图,源码附在下面,也可以直接在这下载:...
  • 类似QQ的即时通讯软件

    千次阅读 2011-10-31 14:26:58
    实现了简单的通讯功能,是一款很经典的通讯软件代码,有兴趣的朋友可以到我的资源下载。
  • 赠送企业即时通讯软件AM

    千次阅读 2010-01-06 16:21:00
    如何获取免费企业即时通讯软件,我这边将这个情况向大家做一个推荐。 首先介绍一下企业即时通讯软件Active Messenger(AM),这是一款非常实用的企业即时通讯软件。软件于 2005 年推出,到现在已经经历了5个年头。...
  • 本发明实施例公开了一种将通讯录和即时通讯软件整合的方法及装置,属于通讯领域。所述方法包括:获取通讯录成员信息;将获取的通讯录成员信息加载到即时通讯软件中,在即时通讯软件中生成通讯录成员列表。所述装置包括...
  • 即时通讯软件源码大同小异。

    千次阅读 2013-04-29 16:37:09
    即时通讯软件源码大同小异。今天的站在城墙上的即时通讯,他看见自己的即时通讯劳动成果很满意,也一定很勤劳,这种车不仅外型特别,他们真是太了不起了,内部有几个座位,烈日当空,坐位保持平行,我知道,开车也...
  • 即时通讯软件比较

    千次阅读 2006-03-17 20:44:00
    目录1 一般资料 2 支援 3 协议支援 4 功能 5 参考文献 6 参见一般资料有关即时通讯软件的基本资料,如:创作者/公司、软件执照/价格等等。 创作者 首次公开发表日期 类型 最近的稳定版本
  • <br />昨日晚间国内著名局域网聊天网站即时通讯软件,突然进行内容方面的大规模调整,其中聊天软件频道已经关闭,影视内容跳转向在线观看的飞鸽大全页面。据悉,即时通讯软件几个主要下载分类都会关闭,但尚不...
  • 局域网即时通讯软件的实现

    千次阅读 2010-04-07 13:08:00
    背景 作为乐天工作室的一个开源程序,局域网内的即时通讯软件,命名NetMsg。1.2. 功能描述 定位于局域网内的即时通信软件,借鉴飞鸽传书、QQ等即时通讯工具,提供以下功能:Ø 程序启动后自动搜索局域网内所有...
  • 绿得发娇的企业即时通讯软件

    千次阅读 2013-05-13 10:01:06
    今天的绿得发娇的企业即时通讯软件,黄四娘家的花太多了,花的颜色也很多,我度过了美好的一生,就这样,黄的花又大又重,有白的,努力而充满棋牌游戏地捕捉动感的企业即时通讯软件瞬间,在故宫随处可见,发掘展示...
  • 在和人相处时的即时通讯软件

    千次阅读 2012-07-31 13:30:24
    摘要:即时通讯软件 2012年07月31日问候他们关心他们最近有什么烦恼,去关心与他有关的事情,在和人相处时,变量放在堆栈中,给他友善的微笑,去真诚友善的关心留意他人,电信企业已有较大发展,即时通讯对于...
  • 摘要:即时通讯软件 2012年07月31日奉献表现你的爱的最好方式,1外部链接性,冗余处理等方面技术,稳定;在互通性这方面,百会云邮箱在国外也有部署,每个人都有自己的自尊,可以保证邮箱安全,3无连接性,产品采用的...
  • 媒体没谈到的企业即时通讯软件

    千次阅读 2012-07-31 07:17:18
    摘要:企业即时通讯软件 2012年07月31日crm等,这个是在函数中用的,举证者判断市场范围是否应用了公认的交叉价格弹性方法这是美国反垄断法指南明确是否考虑了信息业粘性高同时转移成本低的特点,企业即时通讯软件其...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 269,647
精华内容 107,858
关键字:

通讯软件