基于TCP的简单通讯实例

程序设置了连接数限制,当连接服务器的数量超过3时,不再接受其他连接。且只实现了客户端与服务器之间的通信。
服务器端:
<pre name="code" class="csharp">using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;

namespace TestServer
{
    public partial class Form1 : Form
    {
        TcpListener serverListener;
        TcpClient[] client=new TcpClient[3];
        Thread[] recvThread=new Thread[3];
        Thread recvAcceptThread;
        int i = 0;//表示当前建立的连接数
       

        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 开始监听按钮
        /// </summary>
        private void btnStartListen_Click(object sender, EventArgs e)
        {
            serverListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8000);
            serverListener.Start();//表示服务器开始监听
            lblState.Text = "状态:服务器开始异步监听...";
            recvAcceptThread = new Thread(new ThreadStart(acceptRequest));
            recvAcceptThread.Start();
        }

        /// <summary>
        /// 本函数负责接收新的连接请求
        /// </summary>
        private void acceptRequest()
        {
            while (true)
            {
                if (i > 2)
                {
                    serverListener.Stop();//停止监听
                    recvAcceptThread.Suspend() ;//挂起
                }
                else
                {
                    TcpClient tc = serverListener.AcceptTcpClient();
                    client[i] = tc;
                    this.Invoke((EventHandler)(delegate
                    {
                        lboxClients.Items.Add(client[i].Client.RemoteEndPoint.ToString());
                        lblState.Text = "状态:新连接 " + client[i].Client.RemoteEndPoint.ToString() + " 成功!";
                    }));
                    //实例化一个线程并指定该线程执行的函数为recvData
                    recvThread[i] = new Thread(new ParameterizedThreadStart(recvData));
                    recvThread[i].Start(i);
                    i++;
                }
            }
        }

        /// <summary>
        /// 本函数负责数据接收
        /// </summary>
        private void recvData(object ob)
        {
            int k = Convert.ToInt32(ob);
            NetworkStream ns;
            StreamReader sr;
            string str;
            while (true)
            {
                ns= client[k].GetStream();//获取服务端到客户端的网络流
                sr = new StreamReader(ns, System.Text.Encoding.Unicode);
                str = sr.ReadLine();
                this.Invoke((EventHandler)(delegate
                {
                    rtbRecv.Text += str + "\r\n";
                }));
                //因为,这里是在不是创建rtbRecv的线程上访问该控件
                if (str == null)
                {
                    MessageBox.Show("客户端已退出");
                    this.Invoke((EventHandler)(delegate
                    {
                        lboxClients.Items.RemoveAt(k);
                    }));
                    i--;
                    if (i == 2)
                    {
                        serverListener.Start();
                        recvAcceptThread.Resume();
                    }
                    recvThread[k].Abort();//结束接收数据线程
                }

            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            int k = lboxClients.SelectedIndex;//获取你选中对象的索引值
            try 
            {
                NetworkStream ns;
                ns=client[k].GetStream();
                StreamWriter  sw=new StreamWriter(ns,System.Text.Encoding.Unicode) ;
                sw.WriteLine(rtbSend.Text );//将要发送的信息写到网络流
                sw.Flush();//将这个流发出去
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

客户端:
 
 
<pre name="code" class="csharp">using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace TestClient
{
    public partial class Form1 : Form
    {
        TcpListener serverListener;
        TcpClient myclient;
        Thread recvThread;

        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 本按钮负责连接到服务器
        /// </summary>  
         private void btnRequest_Click(object sender, EventArgs e)
        {
            try
            {
                myclient = new TcpClient("127.0.0.1", 8000);
                lblState.Text = "状态:和服务器连接成功!";
                //接下来,连接成功后就应该启动接收数据的线程
                recvThread = new Thread(new ThreadStart(recvData));
                recvThread.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// 本函数负责数据接收
        /// </summary>
         private void recvData()
         {
            NetworkStream ns;
            StreamReader sr;
            string str;
            while (true)
            {
                ns = myclient.GetStream();//获取服务端到客户端的网络流
                sr = new StreamReader(ns, System.Text.Encoding.Unicode);
                str = sr.ReadLine();
                if (str == null)
                {
                    MessageBox.Show("服务器已经关闭!");
                    recvThread.Abort();//结束接收数据线程
                }
                else
                {
                    this.Invoke((EventHandler)(delegate
                    {
                        rtbRecv.Text += str + "\r\n";
                    }));
                    //因为,这里是在不是创建rtbRecv的线程上访问该控件
                }
            }
         }

         private void btnSend_Click(object sender, EventArgs e)
         {
             try
             {
                 NetworkStream ns;
                 ns = myclient.GetStream();
                 StreamWriter sw = new StreamWriter(ns, System.Text.Encoding.Unicode);
                 sw.WriteLine(rtbSend.Text);//将要发送的信息写到网络流
                 sw.Flush();//将这个流发出去
             }
             catch (Exception ex)
             {
                 MessageBox.Show(ex.Message);
             }
         }

         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
         {
             try
             {
                 recvThread.Abort();
                 myclient.Close();
             }
             catch (Exception ex){MessageBox.Show(ex.Message);}
         }
        
    }
}

效果图如下:
 
 
<img src="https://img-blog.csdn.net/20150609210115988?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlubW8yNzc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

猜你喜欢

转载自blog.csdn.net/jinmo277/article/details/46431485
今日推荐