muyuxizi1的博客

沐与兮子的博客

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

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

首先这是登陆界面(艺术细胞不行,不能怪我- -)
这里写图片描述
这是一个类似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
下一篇UnicodeEncodeError: 'ascii' codec can't encode characters_错误的解决办法
想对作者说点什么? 我来说一句

仿QQ聊天系统,基于C#的实现

2016年11月27日 1.33MB 下载

C#做的学生成绩管理系统

2010年04月21日 1.16MB 下载

基于C_S的类似QQ的聊天程序(c#)

2017年10月19日 515KB 下载

没有更多推荐了,返回首页

关闭
关闭