使用C#制作一个完整的聊天系统

原创 2018年04月15日 21:03:08

话不多说,首先给大家看一下整体的运行效果

首先这是登陆界面(艺术细胞不行,不能怪我- -)
这里写图片描述
这是一个类似QQ主界面的界面(虽然不好看,勉强能用)
这里写图片描述
然后双击其中一个名字,进入聊天页面,另外在打开一个界面,实现双方的聊天
这里写图片描述
这里写图片描述
这就是主要的界面了,还有一些忘记密码,注册,完善个人资料等界面都比较简单,就不一一列出了。所以希望这篇博客能帮助到那些想实现一个比较完整的系统的小伙伴。
接下来就是重头戏了,核心代码了
居所周知,我们做这个聊天系统是采用的C/S模式。首先我们在登陆成功之后,都会进入到主界面,而进入到主界面之后,我们的监听线程就会启动,就相当于启动了一个服务器端。然后我们来看看这个监听线程的代码

public void listen()
        {
            Random rd = new Random();
            int port = 8080;//设置聊天程序的端口号
            IPAddress ipaddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];//动态的获取你电脑的Ip地址
            tcplistener = new TcpListener(IPAddress.Any, port);//设置TCP的监听器
            tcplistener.Start();//监听开始
            socketforclient = tcplistener.AcceptSocket();//用监听器获取连接进来的套接字
            if (socketforclient.Connected)//如果有套接字连接了
            {
                label1.Text = "收到了消息";
                networkstream = new NetworkStream(socketforclient);
                streamreader = new StreamReader(networkstream);
                streamwriter = new StreamWriter(networkstream);
                streamreader1 = streamreader;//创建用于传输数据的读写流
            }

        }

监听应该用一个线程来启动,所以在窗体的初始化的时候就启动这个线程。

 private void Form2_Load(object sender, EventArgs e)
        {
        listen1= new Thread(new ThreadStart(listen));
                listen1.Start();
        }

到这里,小伙伴们就会问了,哎,每个登陆进来界面的都是服务器端,那么哪个是客户端呢?
这就是本系统的精妙的地方了。细心的你一定会发现主界面有一个好友列表,当你双击好友的名字的时候,你就会以客户端的形式连接到你所点击的人的服务器端,如果他没有登陆,也就是服务器没有开始服务,那么就会有提示消息,你们也就当然无法进行聊天了。
下面就让我们来看看服务器端的核心代码。
同样的,由于双方都进入了聊天页面,双方都必须有一个接收消息的线程。

 recthread1 = new Thread(new ThreadStart(fwrec));
                recthread1.Start();

然后我们来看看接受消息这个函数

  private void fwrec()
        {
            if (form2.socketforclient.Connected)
            {
                string zhanghao = "";
                string s = form2.streamreader.ReadLine();
                    for (int i = 0; s[i] != '!'; i++)
                    {
                        zhanghao = zhanghao + s[i];
                    }
                    string mysql1;
                    shujuku shujuku2 = new shujuku();
                    OleDbConnection myconn1 = shujuku2.lianjieshujuku();
                    mysql1 = "SELECT 姓名 FROM 好友信息表 WHERE 账号='" + zhanghao + "'";
                    DataSet myds1 = new DataSet();
                    OleDbDataAdapter myda1 = new OleDbDataAdapter(mysql1, myconn1);
                    myda1.Fill(myds1);
                    myconn1.Close();
                    mingzi = myds1.Tables[0].Rows[0]["姓名"].ToString();//这一部分全部都是从数据库中读取数据的,即根据streamreader.ReadLine()读到的账号查找到关于这个好友的一些基本信息,以便于聊天的时候知道是哪个小伙伴发来的消息。如果大家想了解更多关于数据库连接的知识,请留意我的博客
                    string neirong = s.Substring(zhanghao.Length + 1, s.Length - zhanghao.Length - 1);
                    while (neirong!="exit")//除非有一方发送了exit这条消息,否则会一直接受消息
                    {
                        liaotianyemian.Items.Add(DateTime.Now.ToString() + "    " + mingzi);
                        liaotianyemian.Items.Add(neirong);
                        fwrec();
                    }
                    MessageBox.Show(mingzi + "已经结束聊天");
                    form2.networkstream.Close();
                    form2.streamreader.Close();
                    form2.streamwriter.Close();
                    recthread1.Abort();//注意释放资源哦
            }
        }

这就是服务器端接收消息的代码了,是不是觉得其实也不是很难。然后我们来看看服务器端发送消息的代码:

private void button1_Click(object sender, EventArgs e)
        {
            int a = form2.getflag2();//从主界面传过来的参数用于判断是客服端还是服务器端
            string zhanghao = form1.gettextbox1();
            string mysql1;
            shujuku shujuku2 = new shujuku();
            OleDbConnection myconn1 = shujuku2.lianjieshujuku();
            mysql1 = "SELECT 姓名 FROM 好友信息表 WHERE 账号='" + zhanghao + "'";
            DataSet myds1 = new DataSet();
            OleDbDataAdapter myda1 = new OleDbDataAdapter(mysql1, myconn1);
            myda1.Fill(myds1);
            myconn1.Close();
            mingzi = myds1.Tables[0].Rows[0]["姓名"].ToString();
            liaotianyemian.Items.Add(DateTime.Now.ToString() + "    " + mingzi);
            liaotianyemian.Items.Add(textBox1.Text);//也同样的使用了数据库,有兴趣了解数据库知识的童鞋请留意我的博客
            if (a == 1)
            {

                form2.streamwriter.WriteLine(form2.form1.gettextbox1() + "!" + textBox1.Text);
                form2.streamwriter.Flush();
                if (textBox1.Text == "exit")
                {
                    form2.networkstream.Close();
                    form2.streamreader.Close();
                    form2.streamwriter.Close();

                } 
                textBox1.Text = "";
            }
            else
            {

                streamwriter.WriteLine(form2.form1.gettextbox1() + "!" + textBox1.Text);
                streamwriter.Flush();
                if (textBox1.Text == "exit")
                {
                    shifangziyuan();//释放资源的函数
                    return;
                }
                textBox1.Text = "";
            }

        }

不知道大家注意到没有,上面的一段代码,获取了一个标志来判断是客户端还是服务器端发送消息,也就是说客户端和服务器端的发送消息都是用的上一段代码。
接下来我们来讲客户端的实现代码了,当我们加载到聊天界面的时候,我们会获得主菜单初始化的一个标志,以此判断我们这个是客户端还是服务器端。当我们发现是客户端的时候,就要运行客户端的代码了

private void kehuduan()
            {
                try
                {
                    IPAddress ipaddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];//获取本机IP地址
                    string mysql;
                    shujuku shujuku1 = new shujuku();
                    OleDbConnection myconn = shujuku1.lianjieshujuku();
                    mysql = "SELECT * FROM 好友信息表 WHERE 姓名='" + form2.getselectnode() + "'";
                    DataSet myds = new DataSet();
                    OleDbDataAdapter myda = new OleDbDataAdapter(mysql, myconn);
                    myda.Fill(myds);
                    myconn.Close();
                    int port = int.Parse(myds.Tables[0].Rows[0]["端口号"].ToString());//获取数据库中的端口号
                    string hostname = Dns.GetHostEntry(ipaddress).HostName;
                    myclient = new TcpClient(hostname, port);//根据参数建立客户端
                    networkStream = myclient.GetStream();
                    streamreader = new StreamReader(networkStream);
                    streamwriter = new StreamWriter(networkStream);
                    recthread = new Thread(new ThreadStart(recvdata));
                    recthread.Start();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("该用户没有登录");
                    this.Hide();
                }

接下里就是客户端的接收消息的代码了,其实跟上面的服务器端的接受消息的代码差别不大

private void recvdata()
            {
                string zhanghao = "";
                string s = streamreader.ReadLine();
                   for (int i = 0; s[i] != '!'; i++)
                {

                    zhanghao = zhanghao + s[i];
                }
                   string mysql1;
                   shujuku shujuku2 = new shujuku();
                   OleDbConnection myconn1 = shujuku2.lianjieshujuku();
                   mysql1 = "SELECT 姓名 FROM 好友信息表 WHERE 账号='" + zhanghao + "'";
                   DataSet myds1 = new DataSet();
                   OleDbDataAdapter myda1 = new OleDbDataAdapter(mysql1, myconn1);
                   myda1.Fill(myds1);
                   myconn1.Close();
                   mingzi = myds1.Tables[0].Rows[0]["姓名"].ToString();
                   string neirong = s.Substring(zhanghao.Length + 1, s.Length - zhanghao.Length - 1);

                   while (!neirong.Equals("exit"))
                   {
                       liaotianyemian.Items.Add(DateTime.Now.ToString() + "    " + mingzi);
                       liaotianyemian.Items.Add(neirong);
                       recvdata();
                   }
                   MessageBox.Show(mingzi + "已经结束聊天了");
                   recthread.Abort();
                   shifangziyuan();

            }

另外把释放资源的函数留给大家

public void shifangziyuan()
        {
            int a=form2.getflag2();
            if (a == 0)
            {
                networkStream.Close();
                streamreader.Close();
                streamwriter.Close();
                recthread.Abort();
            }

        }

好了!整个步骤大概就介绍到这里了,虽然没有把整个系统所有的代码全部放上来一一介绍。但是最最最重要的代码已经给大家了,小伙伴们可以按照此思路来搭建一个更加完美的系统!
另外:如果大家对此系统的其他功能实现感兴趣的话可以加我qq:826512497
咱们慢慢聊

版权声明: https://blog.csdn.net/muyuxizi1/article/details/79945882

C#简单窗体聊天程序

以前C/S通讯这一块都是基于套接字(Sockets)编程,但是面对业务逻辑复杂的C/S系统,通讯这一块往往都是被封装好了的,前几天写的一个小小窗体聊天程序,主要是练习一下C#封装的TcpListene...
  • wangqiuyun
  • wangqiuyun
  • 2012-08-15 17:24:26
  • 9683

网络<em>聊天</em>软件的设计与实现全套<em>论文</em>

2011-06-<em>23</em> 上传大小:408KB 局域网<em>聊天</em>软件视频<em>聊天</em>语音<em>聊天</em>本科论文 ...C30050网络协议转换<em>系统</em>的设计与实现3万字论文源程序<em>毕业论文</em>毕业设计全套 立即下载...
  • 2018年04月17日 00:00

Android即时聊天系统设计

Android即时聊天系统设计 最近比较闲,当工作比较闲是意味着什么呢(⊙﹏⊙) 于是,总结一下前几个月的毕业设计吧,说不好对一些有需要的朋友有帮助呢,也算是为社会做贡献了( 简单的即时聊天系统...
  • u014303844
  • u014303844
  • 2017-09-20 15:43:07
  • 273

基于JAVA的<em>聊天系统</em>的设计与实现

2012-12-01 上传大小:407KB <em>聊天系统</em>jspjava毕业设计<em>毕业论文</em> 摘 要 随着互联...上传者: a930103063 时间: 2015-12-<em>23</em> 综合评分: 0 积分/C币:3 基于java...
  • 2018年04月17日 00:00

即时消息系统--本科毕业设计

 摘要 随着网络通信技术和计算机技术的进一步发展,即时消息正在成为网络在线活动中不可缺少的业务。本课题在现有的网络通信技术、数据库技术和编程技术的基础上设计并实现了网络即时消息系统。该系统采用三层 C...
  • flydragonfly
  • flydragonfly
  • 2010-10-18 01:12:00
  • 4760

java即时<em>聊天系统 毕业</em>设计及<em>毕业论文</em>

Moe_Loli控 2016-04-<em>23</em> 21:37:46 东西不错!只是不是我想要的 h645702867...java即时<em>聊天系统 毕业</em>设计及<em>毕业论文</em> 会员到期时间: 剩余下载个数: 剩余C币:...
  • 2018年04月18日 00:00

论文

推荐免费下载华软源码网500多套毕业设计下载地址:http://www.hur.cn/tg/bysjlink.asp?linkid=169771下载地址:[URL=http://www.hur.cn/...
  • lsspo
  • lsspo
  • 2011-04-22 00:20:00
  • 3943

用WINSOCK实现聊天室的VC++程序设计

用WINSOCK实现聊天室的VC++程序设计 一、SOCKET简介 80年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大 学Berkeley分校提供了资金,让他们在UNIX操作系统下实现T...
  • andymei
  • andymei
  • 2000-08-23 02:26:00
  • 4661

<em>聊天</em>室<em>系统毕业</em>设计<em>论文</em>,范文

blu<em>cc</em>exu 2016-10-15 <em>23</em>:03:24 写的还不错,用来做<em>论文</em>参考可以 ming418559655...<em>聊天</em>室<em>系统毕业</em>设计<em>论文</em>,范文 会员到期时间: 剩余下载个数: 剩余C币: 剩余...
  • 2018年04月17日 00:00
收藏助手
不良信息举报
您举报文章:使用C#制作一个完整的聊天系统
举报原因:
原因补充:

(最多只允许输入30个字)