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

 更新时间:2020年6月25日 11:39  点击:1627

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
    {
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param ></param>
        /// <returns></returns>
        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;
        }
        /// <summary>
        /// 反列化
        /// </summary>
        /// <param ></param>
        /// <returns></returns>
        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
{
 /// <summary>
 /// 错误日志的输出。
 /// </summary>
 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";
            }
        }
    }
}

[!--infotagslink--]

相关文章

  • C# WinForm多线程解决界面卡死问题的完美解决方案,使用BeginInvoke

    问题描述:当我们的界面需要在程序运行中不断更新数据时,当一个textbox的数据需要变化时,为了让程序执行中不出现界面卡死的现像,最好的方法就是多线程来解决一个主线程来创建界...2020-06-24
  • c# 多线程处理多个数据的方法

    这篇文章主要介绍了c# 多线程处理多个数据的方法,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-03-31
  • C#基于委托实现多线程之间操作的方法

    这篇文章主要介绍了C#基于委托实现多线程之间操作的方法,实例分析了C#的委托机制与多线程交互操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C#多线程中的异常处理操作示例

    这篇文章主要介绍了C#多线程中的异常处理操作,涉及C#多线程及异常的捕获、处理等相关操作技巧,需要的朋友可以参考下...2020-06-25
  • 深入分析C#中的异步和多线程

    这篇文章主要介绍了C#中异步和多线程的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2021-01-16
  • C#多线程与异步的区别详解

    多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别...2020-06-25
  • C#多线程之Thread类详解

    这篇文章主要为大家详细介绍了C#多线程之Thread类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • java中多线程与线程池的基本使用方法

    在Java中,我们可以利用多线程来最大化地压榨CPU多核计算的能力,下面这篇文章主要给大家介绍了关于java中多线程与线程池基本使用的相关资料,需要的朋友可以参考下...2021-09-13
  • C#中的多线程多参数传递详解

    第一种解决方案的原理是:将线程执行的方法和参数都封装到一个类里面。通过实例化该类,方法就可以调用属性来实现间接的类型安全地传递多个参数...2020-06-25
  • java多线程中执行多个程序的实例分析

    在本篇文章里小编给大家整理的是一篇关于java多线程中执行多个程序的实例分析内容,有需要的朋友们可以学习参考下。...2021-02-07
  • 解析C#多线程编程中异步多线程的实现及线程池的使用

    这篇文章主要介绍了C#多线程编程中异步多线程的实现及线程池的使用,同时对多线程的一般概念及C#中的线程同步并发编程作了讲解,需要的朋友可以参考下...2020-06-25
  • Springboot实现多线程注入bean的工具类操作

    这篇文章主要介绍了Springboot实现多线程注入bean的工具类操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-27
  • c# winform 关闭窗体时同时结束线程实现思路

    th.IsBackground = true解决线程问题,意思就是把线程设置为后台线程,感兴趣的朋友可以多了解下,如何有什么妙招还请多多指导哈...2020-06-25
  • C#多线程编程中的锁系统(三)

    这篇文章主要介绍了C#多线程编程中的锁系统(三),本本文主要说下基于内核模式构造的线程同步方式、事件、信号量以及WaitHandle、AutoResetEvent、ManualResetEvent等内容,需要的朋友可以参考下...2020-06-25
  • Java多线程实现简易微信发红包的方法实例

    这篇文章主要给大家介绍了关于Java多线程实现简易微信发红包的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-01
  • c#使用多线程的几种方式示例详解

    这篇文章主要介绍了c#使用多线程的几种方式,通过示例学习c#的多线程使用方式,大家参考使用吧...2020-06-25
  • C#多线程编程中的锁系统(四):自旋锁

    这篇文章主要介绍了C#多线程编程中的锁系统(四):自旋锁,本文讲解了基础知识、自旋锁示例、SpinLock等内容,需要的朋友可以参考下...2020-06-25
  • C#多线程及同步示例简析

    这篇文章主要为大家详细介绍了C#多线程及同步示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • C#多线程ThreadPool线程池详解

    这篇文章主要介绍了C#多线程ThreadPool线程池的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • 浅解关于C#多线程的介绍

    本篇文章小编将为大家介绍,浅解关于C#的多线程,有需要的朋友可以参考一下...2020-06-25