C#做了个多线程网络通信的例子

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace server
{
    class Program
    {
        public static TcpListener myList;
        public static Socket s;
        static void Main(string[] args)
        {
            try
            {
                // 把IP地址转换为IPAddress的实例 先得主机名再得IP
                IPAddress ipAd = IPAddress.Parse(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString());

                // 初始化监听器, 端口为8001
                myList = new TcpListener(ipAd, 8001);

                // 开始监听服务器端口
                myList.Start();

                // 输出服务器启动信息
                Console.WriteLine("在8001端口启动服务...");
                Console.WriteLine("本地节点为:" + myList.LocalEndpoint);
                Console.WriteLine("等待连接.....");
                while (true)
                {
                    // 等待处理接入连接请求
                    // 新建立的连接用套接字s表示 
                    s = myList.AcceptSocket();
                    //AcceptSocket 是一个阻塞方法,它返回可用来发送和接收数据的 Socket。如果希望避免阻塞,您可以使用 Pending 方法来确定传入连接队列中是否有连接请求。

                    //这里用一个新的类来接收s,在类里起一个thread处理 
                    AcceptSocketClass accept = new AcceptSocketClass(s);
                    accept.StartThread();
                }

                // 善后工作,释放资源
                //s.Close();
                //myList.Stop();
            }
            catch (Exception e)
            {
                Console.WriteLine("Error..... " + e.StackTrace);
            }
            Console.ReadLine();
        }
    }
    public class AcceptSocketClass
    {
        public static int times = 0; // 注意这里必须是静态变量(也就是类变量)才能在不同实例中更新它。
        Socket socket;
        public AcceptSocketClass(Socket s)
        {
            socket = s;
        }
        public void StartThread()
        {
            //这个类起一个线程处理你的事件 
            Console.WriteLine("\n连接来自 " + socket.RemoteEndPoint);

            // 接收客户端信息
            byte[] b = new byte[100];
            int k = socket.Receive(b);
            if (k > 0)
            {
                Console.WriteLine("收到第{0}批数据流...", times + 1);
                for (int i = 0; i < k; i++)
                {
                    Console.Write(Convert.ToChar(b[i]));
                }
                Thread td = new Thread(new ParameterizedThreadStart(DoAction));
                td.Start(times);
                times++;
            }
        }
        private void DoAction(object t)
        {
            Console.WriteLine("启动第{0}个线程", (int)t + 1);
            Thread.Sleep(10000);
            Console.WriteLine("第{0}个线程醒了", (int)t + 1);
            // 处理客户端请求,给客户端回应
            ASCIIEncoding asen = new ASCIIEncoding();
            socket.Send(asen.GetBytes("The" + ((int)t + 1).ToString() + "th string was Echoed by the server."));
            Console.WriteLine("\n第{0}个线程已发送回应信息", (int)t + 1);
            Thread.CurrentThread.Abort();//干完就退
        }
    }
}

-----------------------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace client
{
    class Program
    {
        public static int t = 1;
        public static string strHost = "192.168.1.1";//直接用本机IP省事
        public static string str;
        static void Main(string[] args)
        {
            try
            {
                Thread[] myTd = new Thread[100];
                for (int j = 0; j < 100; j++)
                {
                    myTd[j] = new Thread(new ThreadStart(ConstantSend));
                    myTd[j].Start();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error..... " + e.StackTrace);
            }
            Console.ReadLine();
        }
        private static void ConstantSend()//收发在一个线程才能保证端口不错乱
        {
            try
            {
                // 新建客户端套接字
                TcpClient tcpclnt = new TcpClient();
                Console.Write("连接----->");

                // 连接服务器的8001端口,自己不一定用8001端口
                tcpclnt.Connect(strHost, 8001);
                Console.WriteLine("第{0}个连接成功", t);
                t++;
                Console.WriteLine("发送一个'Hi'过去后睡2000ms\n");


                // 得到客户端的流
                Stream stm = tcpclnt.GetStream();

                ASCIIEncoding asen = new ASCIIEncoding();
                str = "Hi" + (t - 1).ToString();
                byte[] ba = asen.GetBytes(str);
                //Console.WriteLine("传输中.....");
                stm.Write(ba, 0, ba.Length);
                Thread.Sleep(2000);

                // 接收从服务器返回的信息
                byte[] bb = new byte[100];
                int k = stm.Read(bb, 0, 100);

                // 输出服务器返回信息
                for (int i = 0; i < k; i++)
                {
                    Console.Write(Convert.ToChar(bb[i]));
                }
                Console.WriteLine();//空行区分下
                // 关闭客户端连接
                tcpclnt.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Error..... " + e.StackTrace);
            }
        }

    }
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 C# WinForm 多线程例子,它使用了 BackgroundWorker 组件来实现多线程处理任务: 1. 在 WinForm 窗体中添加一个按钮和一个 Label 控件。 2. 双击按钮控件,打开 Click 事件处理程序。 3. 在事件处理程序中添加以下代码: ```csharp private void button1_Click(object sender, EventArgs e) { // 启动后台任务 backgroundWorker1.RunWorkerAsync(); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { // 模拟一个长时间运行的任务 for (int i = 0; i < 100; i++) { Thread.Sleep(100); backgroundWorker1.ReportProgress(i); } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { // 更新 Label 控件的显示内容 label1.Text = $"已完成 {e.ProgressPercentage}%"; } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // 显示任务完成提示 MessageBox.Show("任务已完成!"); } ``` 4. 在窗体的构造函数中,添加以下代码: ```csharp public Form1() { InitializeComponent(); // 启用支持多线程的控件样式 Control.CheckForIllegalCrossThreadCalls = false; // 配置 BackgroundWorker 组件 backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = false; } ``` 以上代码的作用如下: - 当用户单击按钮时,启动后台任务; - 后台任务模拟一个长时间运行的任务,每隔一段时间更新一次进度; - 当进度更新时,更新 Label 控件的显示内容; - 当任务完成时,弹出一个提示框。 需要注意的是,在多线程应用程序中,UI 线程和后台线程是分别运行的,不能直接访问 UI 控件。为了避免出现访问冲突,可以启用支持多线程的控件样式,并使用 Invoke 或 CheckForIllegalCrossThreadCalls 属性来解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值