热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

c#多线程网络聊天程序代码分享(服务器端和客户端)

本程序使用VS2005制作,程序分为三块,XuLIeHua类库下有我写的把结构序列化的类,还有就是服务器端和客户端

XuLIeHua类库

代码如下:

using System;
using System.Collections; 
using System.Collections.Generic;
using System.Threading; 
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.IO;
using System.Net;  
using System.Net.Sockets;
namespace XuLIeHua
{
    [Serializable]
    public struct NetMsg
    {
        public IPAddress Fip;     //发送者的IP。
        public string msg;        //发送的消息。
        public IPAddress JieIP;   //接收者的ip。
        public int port;          //端口。
    }
    public class XuLIe
    {
        ///
        /// 序列化
        ///

        ///
        ///
        public static byte[] ObjToByte(object obj)
        {
            byte[] tmp = null;
            MemoryStream fs = new MemoryStream();
            try
            {
                BinaryFormatter Xu = new BinaryFormatter();
                Xu.Serialize(fs, obj);
                tmp = fs.ToArray();
            }
            catch (Exception err)
            {
                throw err;
            }
            finally
            {
                fs.Close();
            }
            return tmp;
        }
        ///
        /// 反列化
        ///

        ///
        ///
        public static object ByteToObj(byte[] tmp)
        {
            MemoryStream fs = null;
            object obj = null;
            try
            {
                fs = new MemoryStream(tmp);
                fs.Position = 0;
                BinaryFormatter Xu = new BinaryFormatter();
                obj = Xu.Deserialize(fs);
            }
            catch (Exception err)
            {
                throw err;
            }
            finally
            {
                fs.Close();
            }
            return obj;
        }
    }
    public class ServerJieShou
    {
        private static TcpClient Client;
        public Thread th;
        private ArrayList Arr;
        private LogText log;
        private bool Tiao = true;
        private Timer time1;
        private TimerCallback time;
        public ServerJieShou(TcpClient sClient, ArrayList arr)
        {
            log = new LogText("连接") ;
            Client = sClient;
            Arr = arr;
            th = new Thread(new ThreadStart(ThSub));
            th.IsBackground = true;
            th.Start();
            time = new TimerCallback(XinTiao);
            time1 = new Timer(time, null, 15000, -1);

        }
        private void XinTiao(object state)
        {
            if (Tiao == true)
            {
                Tiao = false;
            }
            else
            {
                Client = null;
            }
        }
        private void ThSub()
        {
            try
            {
                while (Client != null)
                {
                    NetworkStream Net = Client.GetStream();
                    if (Net.DataAvailable == true) //有数据。
                    {
                        byte[] tmp = new byte[1024];
                        if (Net.CanRead == true)
                        {
                            MemoryStream memory = new MemoryStream();
                            memory.Position = 0;
                            int len = 1;
                            while (len != 0)
                            {
                                if (Net.DataAvailable == false) { break; }
                                len = Net.Read(tmp, 0, tmp.Length);
                                memory.Write(tmp, 0, len);
                            }
                            log.LogWriter("接收完毕"); 
                            NetMsg msg = (NetMsg)XuLIe.ByteToObj(memory.ToArray());
                            log.LogWriter("序列化完毕");
                            TcpClient tcpclient = new TcpClient();
                            log.LogWriter("建立TCP对象");
                            if (msg.Fip != null) //非心跳包。
                            {
                                try
                                {
                                    tcpclient.Connect(msg.JieIP, msg.port);
                                    NetworkStream SubNet = tcpclient.GetStream();
                                    byte[] Tmp = XuLIe.ObjToByte(msg);
                                    SubNet.Write(Tmp, 0, Tmp.Length);
                                }
                                catch (SocketException)
                                {
                                    msg.msg = "对方不在线";
                                    byte[] Tmp = XuLIe.ObjToByte(msg);
                                    Net.Write(Tmp, 0, Tmp.Length);
                                }
                            }
                            else
                            {
                                if (msg.msg == "QUIT")
                                {
                                    Arr.Remove(Client);
                                    return;
                                }
                            }
                            tcpclient.Close();
                            GC.Collect();
                        }
                    }
                    else //没有数据。
                    {
                    }
                    Thread.Sleep(1000);
                }
            }
            catch
            {
                Arr.Remove(Client);
                th.Abort(); 
            }
        }
    }
}

日志输出类

代码如下:

using System;
using System.Text;
using System.IO; 
using System.Windows.Forms;
namespace XuLIeHua
{
 ///
 /// 错误日志的输出。
 ///

 public class LogText
 {
  private string AppPath;
  private StreamWriter StrW;
  private string FileName;
  public LogText(string FileName1)
  {
   AppPath = Application.StartupPath +@"\Log";
   try
   {
    if (Directory.Exists(AppPath) == false)
    {
     Directory.CreateDirectory(AppPath);  
    }
    if (File.Exists(AppPath+@"\"+FileName+".log") == false)
    {
     File.Create(AppPath+@"\"+FileName+".log");
    }
    FileName = FileName1;
   }
   catch{}
  }
  public void LogWriter(string Text)
  {
   try
   {
    StrW = new StreamWriter(AppPath+@"\"+FileName+".log",true);
    StrW.WriteLine("时间:{0} 描述:{1} \r\n",DateTime.Now.ToString(),Text);
    StrW.Flush();
    StrW.Close();
   }
   catch{}
  }
 }
}

服务器

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Threading;
using XuLIeHua;
using System.Net.Sockets;   
using System.Collections;
namespace 服务器
{
    public partial class frmServer : Form
    {
        public frmServer()
        {
            InitializeComponent();
        }
        private ArrayList arr;
        private TcpListener Server1;
        private TcpClient col;
        private ArrayList LianJIe;
        private void frmServer_Load(object sender, EventArgs e)
        {
            arr = new ArrayList();
            LianJIe = new ArrayList();
            Server1 = new TcpListener(Dns.GetHostAddresses(Dns.GetHostName())[0], 8000);
            Server1.Start();
            timer1.Enabled = true;
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {

                if (Server1.Pending() == true)
                {
                    col = Server1.AcceptTcpClient();
                    arr.Add(col);
                    XuLIeHua.ServerJieShou server = new ServerJieShou(col, arr);
                    LianJIe.Add(server); 
                }

                if (arr.Count == 0) { return; }
                listBox1.Items.Clear();
                foreach (TcpClient Col in arr)
                {
                    IPEndPoint ip = (IPEndPoint)Col.Client.RemoteEndPoint;
                    listBox1.Items.Add(ip.ToString());
                }
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
               // Application.Exit(); 
            }
        }
        private void frmServer_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {

                foreach (XuLIeHua.ServerJieShou  Col in LianJIe)
                {
                    Col.th.Abort();  
                    Col.th.Join();  
                }
                foreach (TcpClient Col in arr)
                {

                    Col.Close();
                }
            }
            finally
            {
                Application.Exit();
            }
        }

    }
}

客户端

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Net;
using System.Net.Sockets;
using XuLIeHua;
namespace 客户端
{
    public partial class frmClinet : Form
    {
        public frmClinet()
        {
            InitializeComponent();
        }
        private TcpClient Clinet;
        private NetworkStream net;
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                Clinet = new TcpClient();
                Clinet.Connect(Dns.GetHostAddresses(textBox2.Text)[0], 8000);
                this.Text = "服务器连接成功";
                Thread th = new Thread(new ThreadStart(JieShou));
                th.Start();
                timer1.Enabled = true; 
            }
            catch (SocketException)
            {
                Clinet.Close();
                Clinet = null;
            }

        }
        private void JieShou()
        {
            try
            {
                while(Clinet != null)
                {
                    net = Clinet.GetStream();
                    if (net.CanWrite == false) { Clinet = null; return;}
                    if (net.DataAvailable == true)
                    {
                        byte[] tmp = new byte[1024];
                        MemoryStream memory = new MemoryStream();
                        int len = 1;
                        while (len != 0)
                        {
                            if (net.DataAvailable == false) { break; }
                            len = net.Read(tmp, 0, tmp.Length);
                            memory.Write(tmp, 0, len);
                        }
                        if (memory.ToArray().Length != 4)
                        {
                            NetMsg msg = (NetMsg)XuLIe.ByteToObj(memory.ToArray());
                            textBox1.Text += msg.Fip.ToString() + "说: " + msg.msg + "\r\n";
                        }
                    }
                    Thread.Sleep(200); 
                }
            }
            catch (Exception err)
            {
                lock (textBox1)
                {
                    textBox1.Text = err.Message;
                }
            }
        }
        private void frmClinet_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (net.CanWrite == true)
            {
                NetMsg msg = new NetMsg();
                msg.msg = "QUIT";
                byte[] tmp = XuLIe.ObjToByte(msg);
                try
                {
                    net.Write(tmp, 0, tmp.Length);
                }
                catch (IOException)
                {
                    textBox1.Text += "已经从服务器断开连接\r\n";
                    Clinet.Close();
                    Clinet = null;
                    return;
                }
            }
            Clinet = null;
            GC.Collect();
            Application.ExitThread(); 
        }
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (Clinet != null)
                {
                    if (net != null)
                    {
                        NetMsg msg = new NetMsg();
                        msg.Fip = Dns.GetHostAddresses(Dns.GetHostName())[0];
                        msg.JieIP = Dns.GetHostAddresses(textBox3.Text)[0];
                        msg.msg = textBox4.Text;
                        byte[] tmp = XuLIe.ObjToByte(msg);
                        net.Write(tmp, 0, tmp.Length);
                    }
                }
                else
                {
                    textBox1.Text += "未与服务器建立连接\r\n";
                }
            }
            catch (Exception)
            {
                textBox1.Text += "未与服务器建立连接\r\n";
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                if (Clinet != null)
                {
                    if (net.CanWrite == true)
                    {
                        NetMsg msg = new NetMsg();
                        msg.msg = "0000";
                        byte[] tmp = XuLIe.ObjToByte(msg);
                        try
                        {
                            net.Write(tmp, 0, tmp.Length);
                        }
                        catch (IOException)
                        {
                            textBox1.Text += "已经从服务器断开连接\r\n";
                            Clinet.Close();
                            Clinet = null;
                            return;
                        }

                    }
                }
                else
                {
                    textBox1.Text += "未与服务器建立连接\r\n";
                }
            }
            catch (Exception err)
            {
                textBox1.Text += err.Message +"r\n";
            }
        }
    }
}


推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • Unity3D引擎的体系结构和功能详解
    本文详细介绍了Unity3D引擎的体系结构和功能。Unity3D是一个屡获殊荣的工具,用于创建交互式3D应用程序。它由游戏引擎和编辑器组成,支持C#、Boo和JavaScript脚本编程。该引擎涵盖了声音、图形、物理和网络功能等主题。Unity编辑器具有多语言脚本编辑器和预制装配系统等特点。本文还介绍了Unity的许可证情况。Unity基本功能有限的免费,适用于PC、MAC和Web开发。其他平台或完整的功能集需要购买许可证。 ... [详细]
  • 本文介绍了iOS开发中检测和解决内存泄漏的方法,包括静态分析、使用instruments检查内存泄漏以及代码测试等。同时还介绍了最能挣钱的行业,包括互联网行业、娱乐行业、教育行业、智能行业和老年服务行业,并提供了选行业的技巧。 ... [详细]
  • 概述H.323是由ITU制定的通信控制协议,用于在分组交换网中提供多媒体业务。呼叫控制是其中的重要组成部分,它可用来建立点到点的媒体会话和多点间媒体会议 ... [详细]
  • POCOCLibraies属于功能广泛、轻量级别的开源框架库,它拥有媲美Boost库的功能以及较小的体积广泛应用在物联网平台、工业自动化等领域。POCOCLibrai ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 在Windows 10中点击“检查更新”按钮可能让你成为微软的测试补丁的“小白鼠”。微软每月的第三、第四周会向稳定通道的用户选择性发放“C”“D”测试补丁,而那些主动点击“检查更新”的用户可能会成为这些补丁的测试对象。这些补丁主要用于测试下一个Patch Tuesday的更新内容的稳定性,也可能用于修复个性化问题。因此,用户需要小心点击“检查更新”,以免遭受不必要的风险。 ... [详细]
author-avatar
夜晨在行动
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有