精华内容
下载资源
问答
  • 局域网聊天软件设计与实现(,C++,MySQL)(任务书,中期检查报告,外文翻译,毕业论文16000字,程序代码,MySQL数据库,答辩PPT)摘 要局域网聊天软件是在LINUX系统下运行的一个应用程序程序用c++语言编写。本程序有如下功能...

    局域网聊天软件设计与实现(,C++,MySQL)(任务书,中期检查报告,外文翻译,毕业论文16000字,程序代码,MySQL数据库,答辩PPT)

    摘   要

    局域网聊天软件是在LINUX系统下运行的一个应用程序,程序用c++语言编写。本程序有如下功能:用户列表自动刷新、通过TCP通信协议进行消息收发、MYsql数据库保存用户名与密码。该设计是一个简单的局域网聊天软件,适用于企业内部和实验室使用,不与互联网进行数据交换,具有高速、安全等优势。

    本文着重介绍下列内容:对用户上下线消息通知、聊天消息收发等进行数据解析;TCP网络编程,讲述用TCP    创建Client和Server以及收发数据的实现;最后对本设计的具体实现方法和设计实现流程进行讲解以及程序运行分析。

    关键词: LINUX;TCP;Socket;Mysql数据库;C++

    The Design And Implementation of The LAN Chat Software

    Abstract

    The LAN chat tool is An application under LINUX.The application written by C++ language.This program has the following functions: sending broadcast when login and exit,sending and receiving messages by the TCP communication protocol, using MYsql database to save chat messages. it is most often used to chat in enterprise and laboratory, it is working without data exchange from Internet,so it can transmit data high speed and security.

    This paper focuses on the following contents: the user online and offline message notification, chat message send and receive data analysis; TCP network programming, here tells the method of using TCP to create client and Server to send and receive data;Finally introduce the design method and implementation process of my graduation design and running the application.

    Keywords: LINUX;TCP/IP;Socket;Mysql database;C++

    需求分析

    本项目基于LINUX系统实现在局域网内的聊天软件,软件分为服务端和客户端,要实现的功能如下。

    服务器端:

    (1)能够正确的启动服务器。

    (2)能够监听指定的端口,来等待用户的连接。

    (3)客户端注册时能通过数据库验证用户的注册信息,并把注册结果返回给客户端。

    (4)客户端登陆时能通过数据库验证用户的登陆信息,登陆成功后,把此用户的登录消息通知其他好友。

    (5)登陆成功时,能够向新连接的用户发送已上线的用户名单。

    (6)能够接收客户端的群聊消息请求,并能正确无误地处理请求,并把消息发送到所有已登录的客户端。

    (7)能够接受客户端的私聊消息请求,并能正确无误地处理请求,并把消息发送到特定的客户端。

    (8)当用户断开与服务器端地连接时,服务器能够把连接正确的断开,并把该用户退出的消息通知其他用户。

    (9)能够正确的关闭服务器。

    客户端:

    (1)能够启动应用程序,并与服务器建立连接。

    (2)登陆界面,能够把登录信息正确的发送到服务器。

    (3)能够正确的处理服务器反馈的登结果信息。

    (4)注册界面,能够把注册信息正确的发送到服务器。

    (5)能够正确的处理服务器反馈的注册结果信息。

    (6)登录以后,能够自动的更新用户列表。

    (7)能够把群聊消息正确的发送到服务器。

    (8)能够正确的把群聊消息显示到群聊界面。

    (9)能够把私聊消息正确的发送到服务器。

    (10)能够正确的把私聊消息显示到特定的聊天窗口。

    (11)客户端退出时,能够把该用户的退出消息发送到服务器,并关闭所有聊天窗口。

    535110831cf143026fb592720e2cb376.png

    fe27ca3f2018c1b557e70d99f8a202d3.png

    5f7ef06ce6cf6e0bc9df7d9b7ae2443a.png

    1428d8672563017a3f05a4bd87154ea4.png

    e723ec032f2525d54cf2472ebf8c76f3.png

    硬件环境:

    CPU:Inter(R) Core(TM) i5 2.67GHz

    内存:2.00 GB

    硬盘:500 G

    软件环境:

    操作系统:Ubuntu 12.0.4

    应用软件:QT 5.0.2

    目录

    摘   要    i

    Abstract    ii

    1  绪论    1

    1.1  课题背景    1

    1.2  目的和意义    1

    1.3  研究现状    1

    2  系统分析    3

    2.1  系统理论基础    3

    2.1.1  C/S架构    3

    2.1.2  TCP    3

    2.1.3  Socket    4

    2.1.4  QT编程框架    6

    2.2  可行性研究    10

    2.3  需求分析    11

    2.4  系统运行环境    11

    3  系统设计    12

    3.1  系统结构设计    12

    3.2  客户端服务器功能设计    12

    3.3  客户端设计    13

    3.4  服务器端设计    14

    3.5  群聊和私聊模块的设计    16

    4  程序描述与详细描述    17

    4.1  服务器端验证客户端的登录信息    17

    4.1.1  功能及实现    17

    4.1.2  技术概要    18

    4.2  服务器端处理用户消息    20

    4.2.1  功能及实现    20

    4.2.2  技术概要    21

    4.3  客户端读取服务器发送的数据    23

    4.3.1  功能及实现    23

    4.3.2  技术概要    25

    4.4客户端用户列表的更新    25

    5  系统实现    27

    5.1  登录模块设计    27

    5.2  注册模块设计    28

    5.3  群聊模块设计    29

    5.4  私聊模块设计    32

    结论    34

    参考文献    35

    致谢    36

    展开全文
  • 嵌入式linux局域网聊天软件 设计内容概述 采用Client/Server架构,可以同时连接5个用户,每个用户最多可以拥有20个好友,最多可以加10个群聊,文件传输的限制字节为4096,缓存机制消息最大为50,在这些限制之可以...

    嵌入式linux局域网聊天软件

    设计内容概述

    采用Client/Server架构,可以同时连接5个用户,每个用户最多可以拥有20个好友,最多可以加10个群聊,文件传输的限制字节为4096,缓存机制消息最大为50,在这些限制之内可以实现如下功能:

    • 注册(用户名不重复):选择注册功能,输入账号密码,即可进行账号注册。
    • 登录(单个用户登录,密码输入不可见):用户登录时,输入账号和密码,与服务端储存的信息进行匹配,匹配成功即可登录,匹配失败显示错误信息。
    • 注销(无需再次运行程序便可登录):在功能菜单中可以退出登录。
    • 私聊(仅能对好友进行):用户选择私聊功能后,提示输入用户想要私聊的另一个用户名,然后提示要发送的消息,用户输入后,显示消息发送,处理成功后消息发送到目标用户。目标用户会接受的此消息。
    • 群聊(只能对所在群组进行):用户选择群聊功能后,提示输入用户想要发起群聊的群组名称,然后提示要发送的消息,用户输入后,显示消息发送,处理成功后消息发送到目标群聊用户。群聊的目标用户均会收到此消息。
    • 聊天记录查询(只能获取好友和所在群组的):聊天记录保存在特定的文件中,可以查看私聊、群聊聊天记录。用户选择查看聊天记录功能后,提示输入用户想要查看得聊天记录文件的名称,用户输入后,即可打开聊天信息文件,查看聊天记录。
    • 文件传输(简易版shell寻找文件,分群组和私聊文件传输):可以向好友发送指定文件。用户选择查看文件传输功能后,提示输入用户想要发送文件的另一个用户名,用户输入后,提示用户想要发送文件的文件名称,输入文件名后即可发送。接受方收到文件后,会将此文件保存在特定的文件夹中。
    • 服务端消息和文件传输缓存机制:缓存好友和群组发送的离线文件和消息,待该用户登陆后由服务器返回历史消息。

    开发工具及运行环境概述

    	开发工具:Clion2020.1
    	运行环境:deepin15.11 Desktop
    	编译环境:gcc( Debian 6.3.0-18+deb9u1)6.3.0 20170516
    	编译文件:makefile
    

    在这里插入图片描述

    注册

    【1】client端输入用户名和密码 -> 存于消息结构体mess中 -> 将结构体发送给server端。
    【2】server端接收client发送的结构体 -> 打开存储用户名密码的文件(server/data/user.txt) -> 验证文件中是否已存在该信息 -> 若无,将用户信息存入文件 ->返回注册消息(已存在该用户,重新注册||注册成功)。
    2.2登录
    【1】client端输入用户名和密码 -> 存于结构体中 -> 将结构体发送给server端。
    【2】server端接收client发送的结构体 -> 打开存储用户名密码的文件(server/data/user.txt) -> 读取文件验证用户信息。
    【3】server端匹配正确发送“登陆成功!”消息,匹配失败根据输入的内容判定提示(“密码错误!”、“用户名不存在,请注册新用户”、“用户已登录,请勿重复登录”)消息 -> client端接收,“登陆成功!”则进入功能菜单,其余则继续循环注册登录的菜单。
    【4】若验证成功,server端产生一个新的套接字newfd,将它与用户名封装于同一个结构体中,存储在线用户的信息。将用户信息存入链表中,表示为在线用户。
    消息、存储在线用户信息结构体:

    Client Server消息结构体 (all.h)

    私聊

    【1】client端后台发送好友列表请求信息 -> 存于结构体中 -> 将结构体发送给server端。
    【2】server端接收client发送的结构体 -> 打开存储用户好友信息的文件(server/data/friends/用户名.txt) -> 读取文件返回好友信息。
    【3】client端接收server发送的结构体 -> 分离线程处理打印传输回来的好友信息。
    【4】client端将发送好友对象和消息内容-> 存入发送的结构体中 -> 将结构体发送给server端。
    【5】server端接收client发送的结构体 -> 根据接收者名字在online的链表中查找套接字描述符(若不在线将消息和日志信息存入服务端,待接受者登陆后将消息转发) -> 将消息发送给该接收者client端。
    【6】client端接收server发送的结构体 -> 分离线程处理打印传输回来的好友消息。

    群聊

    【1】client端后台发送群组列表请求信息 -> 存于结构体中 -> 将结构体发送给server端。
    【2】server端接收client发送的结构体 -> 打开存储用户群组信息的文件遍历查找该用户所在的群组(server/data/groups/group*.txt)-> 返回群组信息。
    【3】client端接收server发送的结构体 -> 分离线程处理打印传输回来的群组信息。
    【4】client端将发送群组对象和消息内容-> 存入发送的结构体中 -> 将结构体发送给server端。
    【5】server端接收client发送的结构体 -> 根据群组所有接收者名字在online的链表中查找套接字描述符(若不在线将消息和日志信息存入服务端,待接受者登陆后将消息转发) -> 将消息存入消息结构体发送给该接收者client端。
    【6】client端接收server发送的结构体 -> 分离线程处理打印传输回来的群组消息。

    聊天记录查询

    【1】client端选择文件传输对象的类型(friend||group),后台发送所选类型列表请求信息 -> 存于结构体中 -> 将结构体发送给server端。
    【2】server端接收client发送的结构体 -> 打开存储用户群组(好友)信息的文件遍历查找该用户所在的群组(好友)(server/data/groups/group*.txt||server/friends/用户名.txt)-> 返回群组||好友信息。
    【3】client端接收server发送的结构体 -> 分离线程处理打印传输回来的群组||好友信息。
    【4】client端将查询对象(群组||好友)-> 存入发送的结构体中 -> 将结构体发送给server端。
    【5】server端接收client发送的结构体 -> 根据查询对象读取server端的消息记录文件(server/records/groupchat/group*.txt|| server/records/ privatechat /用户1_用户2(根据字符串大小排序).txt) -> 将文件内容存入消息结构体发送给该接收者client端。
    【6】client端接收server发送的结构体 -> 分离线程处理打印(保存)传输回来的群组消息(文件)。

    文件传输

    【1】client端选择文件传输对象的类型(friend||group),后台发送所选类型列表请求信息 -> 存于结构体中 -> 将结构体发送给server端。
    【2】server端接收client发送的结构体 -> 打开存储用户群组(好友)信息的文件遍历查找该用户所在的群组(好友)(server/data/groups/group*.txt||server/data/friends/用户名.txt)-> 返回群组||好友信息。
    【3】client端接收server发送的结构体 -> 分离线程处理打印传输回来的群组||好友信息。
    【4】client端将发送对象(群组||好友),简易shell读取发送文件的路径和内容 -> 存入发送的结构体中 -> 将结构体发送给server端。
    【5】server端接收client发送的结构体 -> 根据群组所有接收者名字(好友的名字)在online的链表中查找套接字描述符(若不在线将消息和日志信息存入服务端,待接受者登陆后将消息转发) -> 将消息发送给该接收者client端。
    【6】client端接收server发送的结构体 -> 分离线程处理打印(保存)传输回来的群组消息(文件:保存在特定的文件夹中)。

    系统设计流程图

    在这里插入图片描述

    系统使用方法

    makefile编译

    makefile编译

    运行-注册-登录

    运行登录注册

    私聊

    私聊

    群聊

    群聊

    文件传输(私聊&群聊)

    私聊文件传输
    群聊文件传输

    在线人员

    在线人员

    好友&群组聊天记录查询

    好友&群组聊天记录查询

    Sever端离线缓存机制

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    代码

    代码较多,感兴趣的同学可以点击链接下载(https://download.csdn.net/download/lzj_feifei/12575318)。

    参考网站和不足

    聊天室的底层参考的第一位博主的代码,文件传输的简易shell参考的第二位博主的代码(后续补上,有点找不到了,如果是博主看到的话请联系我给您加上):

    准备过程之中有些许的失误,过于重视逻辑功能的完备性,忽视了界面的制作的重要性,不占视觉的优势。基础的功能调试花费了过长时间,后面部分功能(会用到前面功能的部分:服务端离线消息处理调用私聊的函数)应该单拉出来写函数,调用之前函数比较混乱,导致功能和bug修改困难,但是其余部分功能都完成的比较顺利。
    再就是对软件的应用存在一定的意识缺乏,仅将Clion作为写代码的工具,没有充分利用DeBug功能;起初有过将界面和浏览器网页融合和云服务器运行服务端以及功能设计特色等想法,但也只是停留在了最后的功能设计上,总之只要有想法,并付出实践,想法就可以实现,这就是编程的魅力所在。

    展开全文
  • 基于JAVA的聊天系统的设计与实现

    热门讨论 2012-12-01 01:19:55
    经过分析这些情况,该局域网聊天工具采用Eclipse为基本开发环境和java语言进行编写,首先可在短时间建立系统应用原型,然后,对初始原型系统进行不断修正和改进,直到形成可行系统 关键词:局域网 聊天 socket ...
  • 掌握基于SOCKET接口的各种网络API函数的功能调用方法,掌握基于TCP协议的网络程序设计的方法,掌握网络字节数据主机字节数据之间的转换。掌握Windows系统下字符的转换处理,实现一个文本聊天程序,了解语音聊天...

    掌握基于SOCKET接口的各种网络API函数的功能与调用方法,掌握基于TCP协议的网络程序设计的方法,掌握网络字节数据与主机字节数据之间的转换。掌握Windows系统下字符的转换处理,实现一个文本聊天程序,了解语音聊天的实现技术。

    本程序采用win32对话框作为主窗口的界面设计,采用面向链接的Csocket套接字作为局域网内的数据传输的载体。语音聊天部分使用动态链接库sound.dll来实现本地语音的录制与播放。从而完成一个具有局域网内多人在线文字与语音连天功能的聊天室程序。

    1.程序界面设计

    为使设计界面时方便的使用控件,我用对话框窗口作为本程序的主窗口和设置窗口,这样可以非常方便的拖用控件。

    VC6 控件工具栏

    界面设计如下:

    1)程序主窗口:

    程序主界面

    2)程序设置窗口:

    程序设置界面

    3)程序图标

    程序图标

    2.程序基本功能的实现

    1)连接初始化

    void CExample2_ChatRoomDlg::OnTextchat()

    {

        extern bool IsClient;

        extern CString ip;

        extern CString Set_nicname;

        extern int port;

        extern bool IsSetted;

        CString portStr;

        

        if(IsSetted==false){

            AfxMessageBox("请先进行相关参数设置!");

            GlobalSetting SettingDlg;

            SettingDlg.DoModal();

        }

        else

        {

     

        portStr.Format("%d",port);

        // TODO: Add your control notification handler code here

        if(IsClient==true)

        {

            if(!m_bInit)

            {

                //BYTE f0,f1,f2,f3;

                //CString name;

                //((CIPAddressCtrl *)(GetDlgItem(IDC_IPADDRESS)))->GetAddress(f0,f1,f2,f3);

     

     

                //ip.Format("%d.%d.%d.%d",f0,f1,f2,f3);

                m_bClient=true;

                m_clientsocket.Create();

                if(m_clientsocket.Connect(ip,port))

                {

                    m_clientsocket.Init(this);

                    SetWindowText("局域网聊天程序-客户端:"+Set_nicname);

                    SetDlgItemText(IDC_SHOWTEXT,"客户端连接成功!");

                    SetDlgItemText(IDC_STATUS,"客户端| 当前连接的服务器:"+ip+ "|端口:" + portStr +"\r\n"+"昵称:"+Set_nicname);

     

                    m_bInit=true;

                }

                else

                {

                    m_clientsocket.Close();

                    AfxMessageBox("客户端连接失败!");

                    m_bInit=false;

                }

            }    

        }

        else

        {

            if(!m_bInit)

            {

                m_bClient=false;

                m_bInit=true;

                SetWindowText("局域网聊天程序-服务器:"+Set_nicname);

                SetDlgItemText(IDC_STATUS,"服务器|当前IP"+ ip +"|端口:" + portStr +"\r\n" + "昵称:"+Set_nicname);

                //GetDlgItem(IDC_TEXTCHAT)->ModifyStyle(0,WS_DISABLED);

                //GetDlgItem(IDC_SETTING)->ModifyStyle(0,WS_DISABLED);

                if(m_pListenSocket.Init(port,this)==FALSE)

                {

                    m_bInit=false;

                    return;

                }

            }    

        }

                    GetDlgItem(IDC_TEXTCHAT)->EnableWindow(FALSE);

                    GetDlgItem(IDC_SETTING)->EnableWindow(FALSE);

        }

        

    }

    2)待发送文字准备

    获取文本框中文字做相应的处理后赋值给msg.m_strText

    int m_iLineCurrentPos=((CEdit *)(GetDlgItem(IDC_SHOWTEXT)))->GetLineCount();

    ((CEdit *)(GetDlgItem(IDC_SHOWTEXT)))->LineScroll(m_iLineCurrentPos);

    msg.m_strText=nicname+" "+nowtime+"\r\n"+in+" \r\n";

     

    将文本数据传送给套接字子程序,由套接字发送

    if(!m_bClient)

    {

        POSITION pos;

        for(pos=m_connectionList.GetHeadPosition();pos!=NULL;)

        {

            CClientSocket * t= (CClientSocket *)m_connectionList.GetNext(pos);

            t->SendMessage(&msg);

        }

    }

    else

    {

        m_clientsocket.SendMessage(&msg);

    }

    2)语音部分

    初始化套接字

    void CExample2_ChatRoomDlg::OnSound()

    {

        // TODO: Add your control notification handler code here

        if(m_bInit==false)

        {

            AfxMessageBox("检查网络连接!");

            return;

        }

     

        static BOOL issend=TRUE;

        CString ip;

        BYTE f0,f1,f2,f3;

        ((CIPAddressCtrl *)(GetDlgItem(IDC_IPADDRESS)))->GetAddress(f0,f1,f2,f3);

        ip.Format("%d.%d.%d.%d",f0,f1,f2,f3);

        int port=GetDlgItemInt(IDC_PORT);

     

        typedef long _stdcall SETIP(char *);

        typedef void _stdcall SETPORT(int);

        typedef void _stdcall STARTSOUND();

        typedef void _stdcall STOPSOUND();

     

        static HINSTANCE sound=LoadLibrary("../Sound/Sound.dll");

     

        if(issend)

        {

            if(sound!=NULL)

            {

                SETIP *setip=(SETIP*)GetProcAddress(sound,"setIpAddr");

                SETPORT *setport=(SETPORT*)GetProcAddress(sound,"setPort");

                STARTSOUND *start=(STARTSOUND*)GetProcAddress(sound,"SoundStart");

     

                setport(port);

                if(setip(ip.GetBuffer(0)))

                {            

                    start();

                    SetDlgItemText(IDC_SOUND,"停止语音");

                    issend=FALSE;

                    ip.ReleaseBuffer();

                }

                else

                {

                    AfxMessageBox("不能连接到服务器,检查网络环境与设置!");

                    FreeLibrary(sound);

                    return;

                }

     

            }

            else

            {

                AfxMessageBox("sound.dll组件加载失败");

            }

        }

        else

        {

            if(sound!=NULL)

            {

                STOPSOUND *stop= (STOPSOUND*)GetProcAddress(sound,"SoundStop");

                stop();

                FreeLibrary(sound);

            }

            SetDlgItemText(IDC_SOUND,"语音聊天");

            issend=TRUE;

        }

    }

    录制声音

    void CExample2_ChatRoomDlg::OnNewsend()

    {

        // TODO: Add your control notification handler code here

        if(m_willchating==TRUE)

        {

            m_sound.Init(this);

            m_sound.Record();

            SetDlgItemText(IDC_NEWSEND,"停止语音");

            m_willchating=FALSE;

        }

        else

        {

            CSingleLock lock(&m_mutex,TRUE);

            m_sound.StopRecord();

            SetDlgItemText(IDC_NEWSEND,"语音聊天");

            m_willchating=TRUE;

            lock.Unlock();

        }

    }

    播放声音

    void CExample2_ChatRoomDlg::WriteBufferFull(LPARAM lp,WPARAM wp)

    {

        m_sound.Play();//发出本地声音

        CSingleLock lock(&m_mutex,TRUE);

        CMessg msg;

        msg.m_strText="";

        msg.m_tag=1;

        memcpy(msg.m_buffer,m_sound.m_cBufferIn,MAX_BUFFER_SIZE);

        if(!m_bClient)

        {

            POSITION pos;

            for(pos=m_connectionList.GetHeadPosition();pos!=NULL;)

            {

                CClientSocket * t= (CClientSocket *)m_connectionList.GetNext(pos);

                t->SendMessage(&msg);

            }

        }

        else

        {

            m_clientsocket.SendMessage(&msg);

        }

        m_sound.FreeRecordBuffer();

        m_sound.FreePlayBuffer();    

        lock.Unlock();

        

    }

    3.网络传输功能的实现

    1)服务器

    ServerSocket.cpp主要代码如下:

    BOOL CServerSocket::Init(UINT port, CExample2_ChatRoomDlg* dlg)

    {

        m_uPort=port;

        m_dlg=dlg;

        if(Create(m_uPort)==FALSE)

        {

            AfxMessageBox("服务器套接字创建失败……");

            return FALSE;

        }

        if(this->Listen()==FALSE)

        {

            AfxMessageBox("服务器监听错误");

            return FALSE;

        }

        portStr.Format("%d",port);

        m_dlg->SetDlgItemText(IDC_SHOWTEXT,"服务器建立成功!\r\n服务器IP地址:"+ip+" 端口:"+portStr+"\r\n请在客户端中填入该服务器的ip和端口,然后就开始尽情聊天吧!");

        return TRUE;

    }

     

    void CServerSocket::OnAccept(int nErrorCode)

    {

        // TODO: Add your specialized code here and/or call the base class

        m_dlg->ProcessPendingAccept();

        CSocket::OnAccept(nErrorCode);

    }

     

    2)客户端

    ClientSocket.cpp主要代码如下:

    CClientSocket::CClientSocket()

    {

        m_aSessionIn=NULL;

        m_aSessionOut=NULL;

        m_sfSocketFile=NULL;

        m_bInit=false;

        m_bClose=false;

    }

     

    CClientSocket::~CClientSocket()

    {

        if(m_aSessionIn)

            delete m_aSessionIn;

        if(m_aSessionOut)

            delete m_aSessionOut;

        if(m_sfSocketFile)

            delete m_sfSocketFile;

    }

     

     

    // Do not edit the following lines, which are needed by ClassWizard.

    #if 0

    BEGIN_MESSAGE_MAP(CClientSocket, CSocket)

        //{{AFX_MSG_MAP(CClientSocket)

        //}}AFX_MSG_MAP

    END_MESSAGE_MAP()

    #endif    // 0

     

    /

    // CClientSocket member functions

     

    void CClientSocket::OnReceive(int nErrorCode)

    {

        // TODO: Add your specialized code here and/or call the base class

        CSocket::OnReceive(nErrorCode);

        do

        {

            CMessg temp;

            temp.Serialize(*m_aSessionIn);

            m_dlg->m_sMsgList+=temp.m_strText;

            m_dlg->SetDlgItemText(IDC_SHOWTEXT,m_dlg->m_sMsgList);

            

            if(temp.m_tag==1&&m_dlg->m_willchating==FALSE)

                //如果有声音过来并且本机的声音设备已经准备好了则首先在本机发出声音

            {    

                memcpy(m_dlg->m_sound.m_cBufferOut,temp.m_buffer,MAX_BUFFER_SIZE);

            }

            int linenum=((CEdit *)(m_dlg->GetDlgItem(IDC_SHOWTEXT)))->GetLineCount();

            ((CEdit *)(m_dlg->GetDlgItem(IDC_SHOWTEXT)))->LineScroll(linenum);

            if(!m_dlg->m_bClient)

            {

                for(POSITION pos=m_dlg->m_connectionList.GetHeadPosition();pos!=NULL;)

                {

                    CClientSocket * t = (CClientSocket*)m_dlg->m_connectionList.GetNext(pos);

                    if(t->m_hSocket!=this->m_hSocket)

                    {

                        t->SendMessage(&temp);

                    }

                }

            }

        }

        while (!m_aSessionIn->IsBufferEmpty());

    }

     

    void CClientSocket::Init(CExample2_ChatRoomDlg * dlg)

    {

        m_sfSocketFile= new CSocketFile(this);

        m_aSessionIn=new CArchive(m_sfSocketFile,CArchive::load);

        m_aSessionOut=new CArchive(m_sfSocketFile,CArchive::store);

        m_bClose=false;

        this->m_dlg=dlg;

    }

    BOOL CClientSocket::SendMessage(CMessg * msg)

    {

        if (m_aSessionOut != NULL)

        {

            msg->Serialize(*m_aSessionOut);

            m_aSessionOut->Flush();

            return TRUE;

        }

        else

        {

            //对方关闭了连接

            m_bClose=true;

            CloseSocket();

            m_dlg->CloseSessionSocket();

            return FALSE;

        }

    }

     

     

    void CClientSocket::CloseSocket()

    {

        if(m_aSessionIn)

        {

            delete m_aSessionIn;

            m_aSessionIn=NULL;

        }

        if(m_aSessionOut)

        {

            delete m_aSessionOut;

            m_aSessionOut=NULL;

        }

        if(m_sfSocketFile)

        {

            delete m_aSessionOut;

            m_sfSocketFile=NULL;

        }

        Close();

        m_bInit=false;

        m_bClose=true;

    }

    void CClientSocket::OnClose(int nErrorCode)

    {

        // TODO: Add your specialized code here and/or call the base class

        m_bClose=true;

        CloseSocket();

        m_dlg->CloseSessionSocket();    

        CSocket::OnClose(nErrorCode);

    }

    int CClientSocket::GetLocalHostName(CString &sHostName)    //获得本地计算机名称

    {

        char szHostName[256];

        int nRetCode;

        nRetCode=gethostname(szHostName,sizeof(szHostName));

        if(nRetCode!=0)

        {

            //产生错误

            sHostName=_T("没有取得");

            return GetLastError();

        }

        sHostName=szHostName;

        return 0;

    }

    int CClientSocket::GetIpAddress(const CString &sHostName, CString &sIpAddress)//获得本地IP

    {

        struct hostent FAR * lpHostEnt=gethostbyname(sHostName);

        if(lpHostEnt==NULL)

        {

            //产生错误

            sIpAddress=_T("");

            return GetLastError();

        }

        //获取IP

        LPSTR lpAddr=lpHostEnt->h_addr_list[0];

        if(lpAddr)

        {

            struct in_addr inAddr;

            memmove(&inAddr,lpAddr,4);

            //转换为标准格式

            sIpAddress=inet_ntoa(inAddr);

            if(sIpAddress.IsEmpty())

                sIpAddress=_T("没有取得");

        }

        return 0;

    }

    int CClientSocket::GetIpAddress(const CString &sHostName, BYTE &f0,BYTE &f1,BYTE &f2,BYTE &f3)//获得本地IP

    {

        struct hostent FAR * lpHostEnt=gethostbyname(sHostName);

        if(lpHostEnt==NULL)

        {

            //产生错误

            f0=f1=f2=f3=0;

            return GetLastError();

        }

        //获取IP

        LPSTR lpAddr=lpHostEnt->h_addr_list[0];

        if(lpAddr)

        {

            struct in_addr inAddr;

            memmove(&inAddr,lpAddr,4);

            f0=inAddr.S_un.S_un_b.s_b1;

            f1=inAddr.S_un.S_un_b.s_b2;

            f2=inAddr.S_un.S_un_b.s_b3;

            f3=inAddr.S_un.S_un_b.s_b4;

        }

        return 0;

    }

    3.程序附加功能

    以下功能不是核心功能,目的是让程序更方便使用。

    1)设置功能

    开始聊天之前需要进行相关设置,本程序采用全局变量的方式将服务器IP、端口,聊天昵称等参数存储在全局变量中供主程序调用。

    全局变量声明:

    //Global.h

    extern CString Set_nicname;

    extern CString ip;

    extern bool IsClient;

    extern int port;

    extern int count;

    extern bool IsSetted;

     

    设置功能主要实现代码如下:

    void GlobalSetting::OnSave()

    {

        // TODO: Add your control notification handler code here

        //extern CString Set_nicname;

        if(IsDlgButtonChecked(IDC_RADIO_HOST))

            IsClient=false;

        else

            IsClient=true;

        GetDlgItemText(IDC_NICNAMETEXT,Set_nicname);

        BYTE f0,f1,f2,f3;

        extern CString Set_nicname;

        ((CIPAddressCtrl *)(GetDlgItem(IDC_IPADDRESS)))->GetAddress(f0,f1,f2,f3);

        extern CString ip;

        ip.Format("%d.%d.%d.%d",f0,f1,f2,f3);

        extern int port;

        port=GetDlgItemInt(IDC_PORT);

        extern bool IsSetted;

        IsSetted = true;

        CDialog::OnOK();

    }

    void GlobalSetting::OnRadioHost()

    {

        // TODO: Add your control notification handler code here

        SetDlgItemText(IDC_TEXT_HOST,"本机IP");

        SetDlgItemText(IDC_NICNAMETEXT,"服务器");

        BYTE f0,f1,f2,f3;

        CString name;

        CClientSocket::GetLocalHostName(name);

        CClientSocket::GetIpAddress(name,f0,f1,f2,f3);

        ((CIPAddressCtrl *)(GetDlgItem(IDC_IPADDRESS)))->SetAddress(f0,f1,f2,f3);

        //GetDlgItem(IDC_IPADDRESS)->ModifyStyle(0,WS_DISABLED);

        GetDlgItem(IDC_IPADDRESS)->EnableWindow(FALSE);

    }

    void GlobalSetting::OnRadioClient()

    {

        // TODO: Add your control notification handler code here    

        SetDlgItemText(IDC_TEXT_HOST,"输入服务器的IP");

        //GetDlgItem(IDC_IPADDRESS)->ModifyStyle(WS_DISABLED,0);

        GetDlgItem(IDC_IPADDRESS)->EnableWindow(TRUE);

        SetDlgItemText(IDC_NICNAMETEXT,"客户端");

    }

    2)消息时间功能

    每条消息中包含发送此消息的时间。使用getSystemTime()获取系统时间,具体代码如下

    //本函数用于获取当前系统的时间,使用前请传入获取时间的string的引用

    void getSystemTime(CString & stime){

    time_t t = time( 0 );

    char tmp[64];

    strftime( tmp, sizeof(tmp), "%Y/%m/%d %X ",localtime(&t) );

    stime=tmp;

    }

    然后加入到消息内容中发送出去,接收方接受之后进行相应的处理之后显示出来,从而达到显示消息时间的目的

    3)当前运行状态显示

    获取当前状态并显示在主窗口的底部及标题栏上。主要通过获取当前全局变量的值来实现,具体代码如下:

    SetWindowText("局域网聊天程序-客户端:"+Set_nicname);

    SetDlgItemText(IDC_STATUS,"客户端| 当前连接的服务器:"+ip+ "|端口:" + portStr +"\r\n"+"昵称:"+Set_nicname);

     

    SetWindowText("局域网聊天程序-服务器:"+Set_nicname);

    SetDlgItemText(IDC_STATUS,"服务器|当前IP"+ ip +"|端口:" + portStr +"\r\n" + "昵称:"+Set_nicname);

     

    4)回车键发送消息功能

    一般常见的聊天程序都可以直接使用回车键直接发送消息,方便快捷。本程序也设计了回车发送消息的功能,具体实现代码如下:

    void CExample2_ChatRoomDlg::OnInputText()

    {

        if(IsDlgButtonChecked(IDC_ENTERCHECK))

        {

        if(!m_bInit)

        {

            AfxMessageBox("未连接服务器……");

            return;

        }

        CString in;

        CString nicname;

        CMessg msg;

        extern CString Set_nicname;

        GetDlgItemText(IDC_INPUTTEXT,in);

        nicname = Set_nicname;

    getSystemTime(nowtime);                    //得到系统时间

        if(in.GetLength()<1)

        {

            return;

        }

        if(in.GetAt(in.GetLength()-1)=='\n')        //判断是否输入回车,是则发送消息

        {

            in.TrimRight(" ");

            SetDlgItemText(IDC_INPUTTEXT,"");

            if(in.GetLength()>2)

            {

                m_sMsgList+="("+nicname+")"+nowtime+"\r\n"+in+" \r\n";        

                SetDlgItemText(IDC_SHOWTEXT,m_sMsgList);

                int m_iLineCurrentPos=((CEdit *)(GetDlgItem(IDC_SHOWTEXT)))->GetLineCount();

                ((CEdit *)(GetDlgItem(IDC_SHOWTEXT)))->LineScroll(m_iLineCurrentPos);

                msg.m_strText=nicname+" "+nowtime+"\r\n"+in+" \r\n";

                if(!m_bClient)

                {

                    POSITION pos;

                    for(pos=m_connectionList.GetHeadPosition();pos!=NULL;)

                    {

                        CClientSocket * t= (CClientSocket *)m_connectionList.GetNext(pos);

                        t->SendMessage(&msg);

                    }

                }

                else

                {

                    m_clientsocket.SendMessage(&msg);

                }

            }

        }

        }//if(IsDlgButtonChecked(IDC_ENTERCHECK))

    }

    4.程序运行

    程序部分运行截图如下

    连接参数设置、服务器建立与状态显示

     

    客户端连接成功与加入聊天室全局提示

     

    多人在线聊天与退出提示

     

    从一开始的使用recv()与send()函数实现windows控制台聊天应用到使用Csocket套接字方式实现win32窗口聊天程序是一个质的飞越。在这过程中也遇到了很多困难,比如字符转换、设置参数的传送、系统时间的获取、语音的录制与播放以及进入退出聊天室的提示……不过这些问题都基本被一一克服了,最后终于开发出了一个有模有样的聊天室程序还是挺有成就感的。

    程序基本功能已经实现,并且已经可以进行局域网内多人实时在线聊天,但是也有一些不足之处:如语音聊天的回声问题一直没能得到很好的解决,还有既然实现了局域网内的聊天,能不能扩展到广域网呢?这些都是还需要继续思考的问题!

    转载于:https://www.cnblogs.com/leftshine/p/5698737.html

    展开全文
  • 2、可以实现局域网内任意电脑的信息接受发送。 1.2 开发环境 操作系统:Ubuntu 9.04 编译调试环境:VI+GCC+GDB 1.3 关键技术 C语言编程 Linux开发环境中开发工具的使用 Gnome图形设计——GTK+2.0 网络编程中...
  • 1. 实现类似飞鸽的功能,自动侦测局域网内部启动该软件的用户,并显示在用户列表中。 2. 可以进行两个人之间的私聊。 3. 可以群聊。 4. 可以发送文件。 界面要求: 1. 尽量使用图形界面实现,要符合日常软件使用...
  • 基于socket聊天程序编写实验报告

    热门讨论 2009-06-19 10:41:58
    通过delphi编程实现局域网内的一个聊天系统,支持客户服务器、客户客户之间的消息传递,服务器允许多个客户端的聊天的功能,聊天记录的保存和查看的功能等。 三、 实验硬件、软件平台: 1. 硬件平台:多台PC机...
  • 经过分析这些情况,该聊天工具采用Eclipse为基本开发环境和java语言进行编写,首先可在短时间建立系统应用原型,然后,对初始原型系统进行不断修正和改进,直到形成可行系统。 客户端采用C/S结构,管理端采用B/S...
  • 设计主要实现一个Linux下的局域网聊天工具的设计。该设计主要分为两部分,客户端部分和服务器部分。设计实现一个简单的聊天程序,用户名/密码注册和登录,客户端登陆到服务器聊天后,可以在聊天室内其他用户...
  • 使用ADO控件打造另类的聊天

    千次阅读 2005-04-12 11:50:00
    这个是我开始接触编程时的想法,想通过仅用数据库,不采用sock来实现一个简单的在局域网内聊天室,我想这个想法很多人都有过。这个程序本身没什么价值,只是一来把自己当初的设计与大家分享,二来是有鉴于网上对...
    这个是我开始接触编程时的想法,想通过仅用数据库,不采用sock来实现一个简单的在局域网内的聊天室,我想这个想法很多人都有过。这个程序本身没什么价值,只是一来把自己当初的设计与大家分享,二来是有鉴于网上对ADO控件的使用这方面的介绍不是很多,自己算是抛砖引玉吧。

    言归正传,首先用access建立一个数据库chat,接着建两张表格:
    content(name(文本),time(时间),content(文本))
    online(name(文本))

    设计:
    登陆模块:

    1. 选择服务器,也就是网上的共享数据库;
    2. 输入用户名;

    刷新模块:负责刷新显示在线用户,聊天内容(用一个定时器)。
    应用模块:用户的聊天内容的发送,及退出时的提示及相关工作。
    运行效果如下,详情可以查看源代码,里面有详细的注释。


    图一

    选择网上共享的数据库:


    图二


    图三


    图四

      利用对数据库表的数据集的行数判断是否有新的记录加入,如果有,就播放类似qq提示音。需要一提的是程序在stadfx.h中还是得加入ado的声明:

    #import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename / 
    ("EOF", "adoEOF");

    主要是为了处理ADO的数据。
      由于目前vc6.0只支持低版本的access,作为在网络上共享的mdb文件首先要求为低版本,还有要设置相应的权限,这样才能实现对数据库的正常访问。
      时间仓促,没有进行细致的调试,存在诸多错误,还请原谅。程序在XP+VC6.0下调试通过。

    展开全文
  • 4.5 DirectShow程序设计 实例133 音频捕捉 实例134 视频捕捉 第5章 文件系统 5.1 文件的基本操作 实例135 创建和删除文件夹 实例136 把文件删除到回收站中 实例137 清空回收站 5.2 查找文件 实例138 搜索...
  • 4.5 DirectShow程序设计 实例133 音频捕捉 实例134 视频捕捉 第5章 文件系统 5.1 文件的基本操作 实例135 创建和删除文件夹 实例136 把文件删除到回收站中 实例137 清空回收站 5.2 查找文件 实例138 搜索...
  •  4.5 DirectShow程序设计   cc实例133 音频捕捉   cc实例134 视频捕捉  第5章 文件系统   5.1 文件的基本操作   cc实例135 创建和删除文件夹   cc实例136 把文件删除到回收站中   cc实例137 ...
  • 4.5 DirectShow程序设计 实例133 音频捕捉 实例134 视频捕捉 第5章 文件系统 5.1 文件的基本操作 实例135 创建和删除文件夹 实例136 把文件删除到回收站中 实例137 清空回收站 5.2 查找文件 实例138 搜索...
  • 4.5 DirectShow程序设计 实例133 音频捕捉 实例134 视频捕捉 第5章 文件系统 5.1 文件的基本操作 实例135 创建和删除文件夹 实例136 把文件删除到回收站中 实例137 清空回收站 5.2 查找文件 实例138 搜索...
  • 4.5 DirectShow程序设计 实例133 音频捕捉 实例134 视频捕捉 第5章 文件系统 5.1 文件的基本操作 实例135 创建和删除文件夹 实例136 把文件删除到回收站中 实例137 清空回收站 5.2 查找文件 实例138 搜索...
  • 4.5 DirectShow程序设计 实例133 音频捕捉 实例134 视频捕捉 第5章 文件系统 5.1 文件的基本操作 实例135 创建和删除文件夹 实例136 把文件删除到回收站中 实例137 清空回收站 5.2 查找文件 实例138 搜索...
  • 4.5 DirectShow程序设计 实例133 音频捕捉 实例134 视频捕捉 第5章 文件系统 5.1 文件的基本操作 实例135 创建和删除文件夹 实例136 把文件删除到回收站中 实例137 清空回收站 5.2 查找文件 实例138 搜索...
  • 4.5 DirectShow程序设计 实例133 音频捕捉 实例134 视频捕捉 第5章 文件系统 5.1 文件的基本操作 实例135 创建和删除文件夹 实例136 把文件删除到回收站中 实例137 清空回收站 5.2 查找文件 实例138 搜索...
  • cc实例114 网络五子棋 cc实例115 彩票抽奖机 3.12 OpenGL程序设计 cc实例116 制作OpenGL动画 cc实例117 利用OpenGL绘制立体模型 cc实例118 利用OpenGL绘制NURBS曲线 第4章 多媒体技术 4.1 动画 cc...
  • cc实例114 网络五子棋 cc实例115 彩票抽奖机 3.12 OpenGL程序设计 cc实例116 制作OpenGL动画 cc实例117 利用OpenGL绘制立体模型 cc实例118 利用OpenGL绘制NURBS曲线 第4章 多媒体技术 4.1 动画 cc...
  •  4.5 DirectShow程序设计   cc实例133 音频捕捉   cc实例134 视频捕捉  第5章 文件系统   5.1 文件的基本操作   cc实例135 创建和删除文件夹   cc实例136 把文件删除到回收站中   cc实例137 ...
  • Python+语言的可视化编程环境的设计与实现.pdf s3c6410中MFC的研究与应用.pdf VB与VC_环境下基于MapX的二次开发比较.pdf VC++环境下快速可重组测控实验系统的开发.pdf VC6_0与MATLAB7_x混合编程方法研究.pdf VC_6_0...
  • Python+语言的可视化编程环境的设计与实现.pdf s3c6410中MFC的研究与应用.pdf VB与VC_环境下基于MapX的二次开发比较.pdf VC++环境下快速可重组测控实验系统的开发.pdf VC6_0与MATLAB7_x混合编程方法研究.pdf VC_6_0...
  • Python+语言的可视化编程环境的设计与实现.pdf s3c6410中MFC的研究与应用.pdf VB与VC_环境下基于MapX的二次开发比较.pdf VC++环境下快速可重组测控实验系统的开发.pdf VC6_0与MATLAB7_x混合编程方法研究.pdf VC_6_0...
  • 程序开发范例宝典>>

    2012-10-24 10:41:28
    全书包括窗体界面设计、控件应用、组件应用、图形技术、多媒体技术、文件系统、操作系统Windows相关程序、注册表、数据库技术、SQL查询相关技术、LINQ查询技术、报表打印技术、图 表技术、硬件相关开发技术、...
  • Python+语言的可视化编程环境的设计与实现.pdf s3c6410中MFC的研究与应用.pdf VB与VC_环境下基于MapX的二次开发比较.pdf VC++环境下快速可重组测控实验系统的开发.pdf VC6_0与MATLAB7_x混合编程方法研究.pdf VC_6_0...
  • C#程序开发范例宝典(第2版).part02

    热门讨论 2012-11-12 07:55:11
    第1章 窗体界面设计 1 1.1 菜单应用实例 2 实例001 带历史信息的菜单 2 实例002 菜单动态合并 3 实例003 像开始菜单一样漂亮的菜单 4 实例004 任务栏托盘菜单 4 实例005 可以拉伸的菜单界面 5 实例006 ...
  • C#程序开发范例宝典(第2版).part13

    热门讨论 2012-11-12 20:17:14
    第1章 窗体界面设计 1 1.1 菜单应用实例 2 实例001 带历史信息的菜单 2 实例002 菜单动态合并 3 实例003 像开始菜单一样漂亮的菜单 4 实例004 任务栏托盘菜单 4 实例005 可以拉伸的菜单界面 5 实例006 ...
  • 第1章 窗体界面设计 1 1.1 菜单应用实例 2 实例001 带历史信息的菜单 2 实例002 菜单动态合并 3 实例003 像开始菜单一样漂亮的菜单 4 实例004 任务栏托盘菜单 4 实例005 可以拉伸的菜单界面 5 实例006 ...

空空如也

空空如也

1 2 3 4
收藏数 65
精华内容 26
关键字:

局域网内聊天程序设计与实现