Tcpclient简单聊天程序

以前C/S通讯这一块都是基于套接字(Sockets)编程,但是面对业务逻辑复杂的C/S系统,通讯这一块往往都是被封装好了的,前几天写的一个小小窗体聊天程序,主要是练习一下C#封装的TcpListener、TcpClient以及NetworkStream的使用,直接看图上代码:

  1. using System;
  2. using System.Drawing;
  3. using System.Collections;
  4. using System.ComponentModel;
  5. using System.Windows.Forms;
  6. using System.Data;
  7. using System.Net;
  8. using System.Net.Sockets;
  9. using System.Threading;
  10. using System.IO;
  11. namespace ChartTestServer
  12. {
  13. public partial class Form1 : Form
  14. {
  15. public Form1()
  16. {
  17. InitializeComponent();
  18. }
  19. private NetworkStream networkStream;
  20. private StreamReader streamReader;
  21. private StreamWriter streamWriter;
  22. private Socket socketForClient;
  23. private TcpListener tcpListener;
  24. private Thread serverThread;// 启动服务线程
  25. private Thread recvThread;// 接收信息线程
  26. private void button1_Click(object sender, EventArgs e)
  27. {
  28. serverThread = new Thread(new ThreadStart(Listen));
  29. serverThread.Start();
  30. }
  31. //[STAThread]
  32. private void Listen()
  33. {
  34. try
  35. {
  36. Int32 port = Int32.Parse(txtPort.Text);
  37. IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
  38. tcpListener = new TcpListener(ipAddress, port);
  39. // 开始侦听
  40. tcpListener.Start();
  41. listBox1.Items.Add("服务已经启动!");
  42. button1.Enabled = false;
  43. button2.Enabled = true;
  44. // 返回可以用以处理连接的Socket实例
  45. socketForClient = tcpListener.AcceptSocket();
  46. // 如果返回值是"true",则产生的套节字已经接受来自远方的连接请求
  47. if (socketForClient.Connected)
  48. {
  49. button3.Enabled = true;
  50. listBox1.Items.Add("客户端成功连接上服务器!");
  51. // 创建networkStream对象通过网络套节字来接受和发送数据
  52. networkStream = new NetworkStream(socketForClient);
  53. // 从当前数据流中读取一行字符,返回值是字符串
  54. streamReader = new StreamReader(networkStream);
  55. streamWriter = new StreamWriter(networkStream);
  56. recvThread = new Thread(new ThreadStart(RecvData));
  57. recvThread.Start();
  58. }
  59. }
  60. catch (Exception exc)
  61. {
  62. MessageBox.Show(exc.Message, "Server提示");
  63. }
  64. }
  65. // 接收服务器发来的信息
  66. private void RecvData()
  67. {
  68. string msg = streamReader.ReadLine();
  69. // 如果不是接收到客户端发来的退出信息,则不断接收信息
  70. while (!msg.Equals("exit"))
  71. {
  72. //statusChart1.Value = Convert.ToInt32(msg);
  73. listBox1.Items.Add("收到信息: " + msg);
  74. msg = streamReader.ReadLine();
  75. }
  76. // 如果接收到客户的退出信息,则退出服务
  77. button1.Enabled = true;
  78. button2.Enabled = false;
  79. button3.Enabled = false;
  80. listBox1.Items.Add("客户已经关闭");
  81. listBox1.Items.Add("服务器关闭");
  82. // 关闭资源
  83. ReleaseResource();
  84. }
  85. private void button3_Click(object sender, EventArgs e)
  86. {
  87. Thread sendThread = new Thread(new ThreadStart(SendData));
  88. sendThread.Start();
  89. }
  90. private void SendData()
  91. {
  92. if (txtMsg.Text != "")
  93. {
  94. listBox1.Items.Add("发送信息: " + txtMsg.Text);
  95. // 往当前的数据流中写入一行字符串
  96. streamWriter.WriteLine(txtMsg.Text);
  97. // 刷新当前数据流中的数据
  98. streamWriter.Flush();
  99. txtMsg.Text = ""; // 清空
  100. }
  101. else
  102. {
  103. MessageBox.Show("发送信息不能为空","提示");
  104. }
  105. }
  106. private void button2_Click(object sender, EventArgs e)
  107. {
  108. try
  109. {
  110. if (button3.Enabled == true)
  111. {
  112. // 停止服务后,允许 启动服务,但是不允许发送消息
  113. button1.Enabled = true;
  114. button2.Enabled = false;
  115. button3.Enabled = false;
  116. string exitMsg = "exit"; // 要退出时,发送 exit 信息给客户端
  117. streamWriter.WriteLine(exitMsg);
  118. // 刷新当前数据流中的数据
  119. streamWriter.Flush();
  120. listBox1.Items.Add("服务器关闭");
  121. // 释放资源
  122. recvThread.Abort();
  123. ReleaseResource();
  124. }
  125. else
  126. {
  127. // 停止服务后,允许 启动服务,但是不允许发送消息
  128. button1.Enabled = true;
  129. button2.Enabled = false;
  130. button3.Enabled = false;
  131. listBox1.Items.Add("服务器关闭");
  132. // 关闭TCP连接,关闭线程
  133. tcpListener.Stop();
  134. serverThread.Abort();
  135. }
  136. }
  137. catch (Exception exc)
  138. {
  139. MessageBox.Show(exc.Message, "Server提示");
  140. }
  141. }
  142. // 释放资源
  143. private void ReleaseResource()
  144. {
  145. networkStream.Close();
  146. streamReader.Close();
  147. streamWriter.Close();
  148. socketForClient.Shutdown(SocketShutdown.Both);
  149. socketForClient.Close();
  150. tcpListener.Stop();
  151. }
  152. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  153. {
  154. // 在未停止 服务 前,不允许关闭窗体
  155. if (button1.Enabled == false)
  156. {
  157. MessageBox.Show("请先停止服务!", "Server提示");
  158. e.Cancel = true;
  159. }
  160. }
  161. private void Form1_Load(object sender, EventArgs e)
  162. {
  163. // 在没有启动服务器之前,不允许停止服务以及发送信息
  164. button2.Enabled = false;
  165. button3.Enabled = false;
  166. }
  167. }
  1. using System;  
  2. using System.Drawing;  
  3. using System.Collections;  
  4. using System.ComponentModel;  
  5. using System.Windows.Forms;  
  6. using System.Data;  
  7. using System.Net;  
  8. using System.Net.Sockets;  
  9. using System.Threading;  
  10. using System.IO;  
  11.   
  12.   
  13. namespace ChartTestServer  
  14. {  
  15.     public partial class Form1 : Form  
  16.     {  
  17.         public Form1()  
  18.         {  
  19.             InitializeComponent();  
  20.         }  
  21.   
  22.         private NetworkStream networkStream;  
  23.         private StreamReader streamReader;  
  24.         private StreamWriter streamWriter;  
  25.         private Socket socketForClient;  
  26.         private TcpListener tcpListener;  
  27.         private Thread serverThread;   // 启动服务线程   
  28.         private Thread recvThread;// 接收信息线程   
  29.   
  30.         private void button1_Click(object sender, EventArgs e)  
  31.         {  
  32.             serverThread = new Thread(new ThreadStart(Listen));  
  33.             serverThread.Start();  
  34.         }  
  35.   
  36.         //[STAThread]   
  37.   
  38.         private void Listen()  
  39.         {  
  40.             try  
  41.             {  
  42.                 Int32 port = Int32.Parse(txtPort.Text);  
  43.                 IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];  
  44.                 tcpListener = new TcpListener(ipAddress, port);  
  45.                 // 开始侦听   
  46.                 tcpListener.Start();  
  47.                 listBox1.Items.Add("服务已经启动!");  
  48.                 button1.Enabled = false;  
  49.                 button2.Enabled = true;  
  50.   
  51.                 // 返回可以用以处理连接的Socket实例   
  52.                 socketForClient = tcpListener.AcceptSocket();  
  53.   
  54.                 // 如果返回值是"true",则产生的套节字已经接受来自远方的连接请求   
  55.                 if (socketForClient.Connected)  
  56.                 {  
  57.                     button3.Enabled = true;  
  58.                     listBox1.Items.Add("客户端成功连接上服务器!");  
  59.                     // 创建networkStream对象通过网络套节字来接受和发送数据   
  60.                     networkStream = new NetworkStream(socketForClient);  
  61.                     // 从当前数据流中读取一行字符,返回值是字符串   
  62.                     streamReader = new StreamReader(networkStream);  
  63.                     streamWriter = new StreamWriter(networkStream);  
  64.                     recvThread = new Thread(new ThreadStart(RecvData));  
  65.                     recvThread.Start();  
  66.                 }  
  67.             }  
  68.             catch (Exception exc)  
  69.             {  
  70.                 MessageBox.Show(exc.Message, "Server提示");  
  71.             }  
  72.   
  73.         }  
  74.   
  75.         // 接收服务器发来的信息   
  76.         private void RecvData()  
  77.         {  
  78.             string msg = streamReader.ReadLine();  
  79.             // 如果不是接收到客户端发来的退出信息,则不断接收信息   
  80.             while (!msg.Equals("exit"))  
  81.             {  
  82.                 //statusChart1.Value = Convert.ToInt32(msg);   
  83.                 listBox1.Items.Add("收到信息: " + msg);  
  84.                 msg = streamReader.ReadLine();  
  85.             }  
  86.             // 如果接收到客户的退出信息,则退出服务   
  87.             button1.Enabled = true;  
  88.             button2.Enabled = false;  
  89.             button3.Enabled = false;  
  90.             listBox1.Items.Add("客户已经关闭");  
  91.             listBox1.Items.Add("服务器关闭");  
  92.             // 关闭资源   
  93.             ReleaseResource();  
  94.         }  
  95.   
  96.         private void button3_Click(object sender, EventArgs e)  
  97.         {  
  98.             Thread sendThread = new Thread(new ThreadStart(SendData));  
  99.             sendThread.Start();  
  100.         }  
  101.   
  102.         private void SendData()  
  103.         {  
  104.             if (txtMsg.Text != "")  
  105.             {  
  106.                 listBox1.Items.Add("发送信息: " + txtMsg.Text);  
  107.                 // 往当前的数据流中写入一行字符串   
  108.                 streamWriter.WriteLine(txtMsg.Text);  
  109.                 // 刷新当前数据流中的数据   
  110.                 streamWriter.Flush();  
  111.                 txtMsg.Text = "";  // 清空   
  112.             }  
  113.             else  
  114.             {  
  115.                 MessageBox.Show("发送信息不能为空", "提示");  
  116.             }  
  117.         }  
  118.   
  119.         private void button2_Click(object sender, EventArgs e)  
  120.         {  
  121.             try  
  122.             {  
  123.                 if (button3.Enabled == true)  
  124.                 {  
  125.                     // 停止服务后,允许 启动服务,但是不允许发送消息   
  126.                     button1.Enabled = true;  
  127.                     button2.Enabled = false;  
  128.                     button3.Enabled = false;  
  129.                     string exitMsg = "exit";  // 要退出时,发送 exit 信息给客户端   
  130.                     streamWriter.WriteLine(exitMsg);  
  131.                     // 刷新当前数据流中的数据   
  132.                     streamWriter.Flush();  
  133.                     listBox1.Items.Add("服务器关闭");  
  134.   
  135.                     // 释放资源   
  136.                     recvThread.Abort();  
  137.                     ReleaseResource();  
  138.                 }  
  139.                 else  
  140.                 {  
  141.                     // 停止服务后,允许 启动服务,但是不允许发送消息   
  142.                     button1.Enabled = true;  
  143.                     button2.Enabled = false;  
  144.                     button3.Enabled = false;  
  145.                     listBox1.Items.Add("服务器关闭");  
  146.   
  147.                     // 关闭TCP连接,关闭线程   
  148.                     tcpListener.Stop();  
  149.                     serverThread.Abort();  
  150.                 }  
  151.             }  
  152.             catch (Exception exc)  
  153.             {  
  154.                 MessageBox.Show(exc.Message, "Server提示");  
  155.             }  
  156.         }  
  157.   
  158.         // 释放资源   
  159.         private void ReleaseResource()  
  160.         {  
  161.             networkStream.Close();  
  162.             streamReader.Close();  
  163.             streamWriter.Close();  
  164.             socketForClient.Shutdown(SocketShutdown.Both);  
  165.             socketForClient.Close();  
  166.             tcpListener.Stop();  
  167.         }  
  168.   
  169.         private void Form1_FormClosing(object sender, FormClosingEventArgs e)  
  170.         {  
  171.             // 在未停止 服务 前,不允许关闭窗体   
  172.             if (button1.Enabled == false)  
  173.             {  
  174.                 MessageBox.Show("请先停止服务!", "Server提示");  
  175.                 e.Cancel = true;  
  176.             }  
  177.         }  
  178.   
  179.         private void Form1_Load(object sender, EventArgs e)  
  180.         {  
  181.             // 在没有启动服务器之前,不允许停止服务以及发送信息   
  182.             button2.Enabled = false;  
  183.             button3.Enabled = false;  
  184.         }  
  185.   
  186.   
  187.     }  
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;


namespace ChartTestServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private NetworkStream networkStream;
        private StreamReader streamReader;
        private StreamWriter streamWriter;
        private Socket socketForClient;
        private TcpListener tcpListener;
        private Thread serverThread;   // 启动服务线程
        private Thread recvThread;// 接收信息线程

        private void button1_Click(object sender, EventArgs e)
        {
            serverThread = new Thread(new ThreadStart(Listen));
            serverThread.Start();
        }

        //[STAThread]

        private void Listen()
        {
            try
            {
                Int32 port = Int32.Parse(txtPort.Text);
                IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
                tcpListener = new TcpListener(ipAddress, port);
                // 开始侦听
                tcpListener.Start();
                listBox1.Items.Add("服务已经启动!");
                button1.Enabled = false;
                button2.Enabled = true;

                // 返回可以用以处理连接的Socket实例
                socketForClient = tcpListener.AcceptSocket();

                // 如果返回值是"true",则产生的套节字已经接受来自远方的连接请求
                if (socketForClient.Connected)
                {
                    button3.Enabled = true;
                    listBox1.Items.Add("客户端成功连接上服务器!");
                    // 创建networkStream对象通过网络套节字来接受和发送数据
                    networkStream = new NetworkStream(socketForClient);
                    // 从当前数据流中读取一行字符,返回值是字符串
                    streamReader = new StreamReader(networkStream);
                    streamWriter = new StreamWriter(networkStream);
                    recvThread = new Thread(new ThreadStart(RecvData));
                    recvThread.Start();
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Server提示");
            }

        }

        // 接收服务器发来的信息
        private void RecvData()
        {
            string msg = streamReader.ReadLine();
            // 如果不是接收到客户端发来的退出信息,则不断接收信息
            while (!msg.Equals("exit"))
            {
                //statusChart1.Value = Convert.ToInt32(msg);
                listBox1.Items.Add("收到信息: " + msg);
                msg = streamReader.ReadLine();
            }
            // 如果接收到客户的退出信息,则退出服务
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            listBox1.Items.Add("客户已经关闭");
            listBox1.Items.Add("服务器关闭");
            // 关闭资源
            ReleaseResource();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Thread sendThread = new Thread(new ThreadStart(SendData));
            sendThread.Start();
        }

        private void SendData()
        {
            if (txtMsg.Text != "")
            {
                listBox1.Items.Add("发送信息: " + txtMsg.Text);
                // 往当前的数据流中写入一行字符串
                streamWriter.WriteLine(txtMsg.Text);
                // 刷新当前数据流中的数据
                streamWriter.Flush();
                txtMsg.Text = "";  // 清空
            }
            else
            {
                MessageBox.Show("发送信息不能为空", "提示");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                if (button3.Enabled == true)
                {
                    // 停止服务后,允许 启动服务,但是不允许发送消息
                    button1.Enabled = true;
                    button2.Enabled = false;
                    button3.Enabled = false;
                    string exitMsg = "exit";  // 要退出时,发送 exit 信息给客户端
                    streamWriter.WriteLine(exitMsg);
                    // 刷新当前数据流中的数据
                    streamWriter.Flush();
                    listBox1.Items.Add("服务器关闭");

                    // 释放资源
                    recvThread.Abort();
                    ReleaseResource();
                }
                else
                {
                    // 停止服务后,允许 启动服务,但是不允许发送消息
                    button1.Enabled = true;
                    button2.Enabled = false;
                    button3.Enabled = false;
                    listBox1.Items.Add("服务器关闭");

                    // 关闭TCP连接,关闭线程
                    tcpListener.Stop();
                    serverThread.Abort();
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Server提示");
            }
        }

        // 释放资源
        private void ReleaseResource()
        {
            networkStream.Close();
            streamReader.Close();
            streamWriter.Close();
            socketForClient.Shutdown(SocketShutdown.Both);
            socketForClient.Close();
            tcpListener.Stop();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 在未停止 服务 前,不允许关闭窗体
            if (button1.Enabled == false)
            {
                MessageBox.Show("请先停止服务!", "Server提示");
                e.Cancel = true;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 在没有启动服务器之前,不允许停止服务以及发送信息
            button2.Enabled = false;
            button3.Enabled = false;
        }


    }
  1. using System;
  2. using System.Drawing;
  3. using System.Collections;
  4. using System.ComponentModel;
  5. using System.Windows.Forms;
  6. using System.Data;
  7. using System.Net;
  8. using System.Net.Sockets;
  9. using System.Threading;
  10. using System.IO;
  11. namespace ChartTest
  12. {
  13. public partial class Form1 : Form
  14. {
  15. public Form1()
  16. {
  17. InitializeComponent();
  18. }
  19. private NetworkStream networkStream;
  20. private StreamReader streamReader;
  21. private StreamWriter streamWriter;
  22. private TcpClient myclient;
  23. private Thread recvThread; // 接收信息线程
  24. private Thread sendThread;// 发送信息线程
  25. private Thread serverThread;// 服务线程
  26. private Thread st;
  27. private void button1_Click(object sender, EventArgs e)
  28. {
  29. serverThread = new Thread(new ThreadStart(Connection));
  30. serverThread.Start();
  31. }
  32. private void Connection()
  33. {
  34. /*
  35. try
  36. {
  37. IPAddress ipAddress = IPAddress.Parse(txtIP.Text);
  38. Int32 port = Int32.Parse(txtPort.Text);
  39. IPEndPoint ipe = new IPEndPoint(ipAddress, port);
  40. myclient = new TcpClient();
  41. myclient.Connect(ipe);
  42. }
  43. catch
  44. {
  45. MessageBox.Show("没有连接到服务器!");
  46. return;
  47. }
  48. */
  49. try
  50. {
  51. IPAddress ipAddress = IPAddress.Parse(txtIP.Text);
  52. Int32 port = Int32.Parse(txtPort.Text);
  53. string hostName = Dns.GetHostEntry(ipAddress).HostName;
  54. myclient = new TcpClient(hostName, port);
  55. }
  56. catch
  57. {
  58. MessageBox.Show("没有连接到服务器!");
  59. return;
  60. }
  61. listBox1.Items.Add("客户端成功连接上服务器!");
  62. button1.Enabled = false; // 连接上了,不让按“连接”按钮
  63. button2.Enabled = true;
  64. button3.Enabled = true;
  65. networkStream = myclient.GetStream();
  66. streamReader = new StreamReader(networkStream);
  67. streamWriter = new StreamWriter(networkStream);
  68. // 创建接收信息线程,并启动
  69. recvThread = new Thread(new ThreadStart(RecvData));
  70. recvThread.Start();
  71. }
  72. // 接收数据
  73. private void RecvData()
  74. {
  75. string s = streamReader.ReadLine();
  76. // 如果没接到服务器退出的消息,则继续接收信息
  77. while (s!=null&&!s.Equals("exit"))
  78. {
  79. listBox1.Items.Add("收到信息:" + s);
  80. s = streamReader.ReadLine();
  81. }
  82. // 收到服务器退出的消息,释放资源
  83. listBox1.Items.Add("服务器关闭");
  84. listBox1.Items.Add("客户端关闭");
  85. button1.Enabled = true;
  86. button2.Enabled = false;
  87. button3.Enabled = false;
  88. // streamReader.Close();
  89. // streamWriter.Close();
  90. // networkStream.Close();
  91. // myclient.Close();
  92. ReleaseResouce();
  93. }
  94. private void button2_Click(object sender, EventArgs e)
  95. {
  96. button1.Enabled = true; // 按了停止之后,“连接”按钮可以用,“发送”不能用
  97. button2.Enabled = false;
  98. button3.Enabled = false;
  99. string exitMsg = "exit"; // 要退出时,发送 exit 信息给服务器
  100. streamWriter.WriteLine(exitMsg);
  101. //刷新当前数据流中的数据
  102. streamWriter.Flush();
  103. listBox1.Items.Add("客户端关闭");
  104. ReleaseResouce();
  105. }
  106. private void button3_Click(object sender, EventArgs e)
  107. {
  108. // 启动发送线程
  109. sendThread = new Thread(new ThreadStart(SendData));
  110. sendThread.Start();
  111. }
  112. // 发送数据
  113. private void SendData()
  114. {
  115. // 发送信息不允许为空
  116. if (txtMsg.Text == "")
  117. {
  118. MessageBox.Show("发送的信息不能为空!");
  119. txtMsg.Focus();
  120. return;
  121. }
  122. try
  123. {
  124. //往当前的数据流中写入一行字符串
  125. streamWriter.WriteLine(txtMsg.Text);
  126. //刷新当前数据流中的数据
  127. streamWriter.Flush();
  128. listBox1.Items.Add("发送信息:" + txtMsg.Text);
  129. txtMsg.Text = ""; // 清空
  130. }
  131. catch (Exception exc)
  132. {
  133. MessageBox.Show(exc.Message, "ClientClient提示");
  134. }
  135. }
  136. private void Form1_Load(object sender, EventArgs e)
  137. {
  138. // 在未连接服务器前,不能发送信息和停止
  139. button2.Enabled = false;
  140. button3.Enabled = false;
  141. }
  142. // 释放资源
  143. private void ReleaseResouce()
  144. {
  145. networkStream.Close();
  146. streamReader.Close();
  147. streamWriter.Close();
  148. if (sendThread!=null&&sendThread.IsAlive)
  149. {
  150. sendThread.Abort();
  151. }
  152. if (recvThread.IsAlive)
  153. {
  154. recvThread.Abort();
  155. }
  156. if (serverThread.IsAlive)
  157. {
  158. serverThread.Abort();
  159. }
  160. myclient.Close();
  161. }
  162. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  163. {
  164. // 如果是在连接中,则不允许关闭窗口
  165. if (button1.Enabled == false)
  166. {
  167. MessageBox.Show("请先停止连接!","ClientClient提示");
  168. e.Cancel = true;
  169. }
  170. }
  171. private void button4_Click(object sender, EventArgs e)
  172. {
  173. // 启动发送线程
  174. st = new Thread(new ThreadStart(SeData));
  175. st.Start();
  176. }
  177. // 发送数据
  178. private void SeData()
  179. {
  180. Random r = new Random();
  181. for (int i = 0; i < 10000; i++)
  182. {
  183. Thread.Sleep(400);
  184. try
  185. {
  186. //往当前的数据流中写入一行字符串
  187. streamWriter.WriteLine(r.Next(80).ToString());
  188. //刷新当前数据流中的数据
  189. streamWriter.Flush();
  190. listBox1.Items.Add("发送信息:" + r.Next(80).ToString());
  191. }
  192. catch (Exception exc)
  193. {
  194. MessageBox.Show(exc.Message, "ClientClient提示");
  195. }
  196. }
  197. }
  198. private void button5_Click(object sender, EventArgs e)
  199. {
  200. st.Abort();
  201. }
  202. }
  203. }
  1. using System;  
  2. using System.Drawing;  
  3. using System.Collections;  
  4. using System.ComponentModel;  
  5. using System.Windows.Forms;  
  6. using System.Data;  
  7. using System.Net;  
  8. using System.Net.Sockets;  
  9. using System.Threading;  
  10. using System.IO;  
  11.   
  12.   
  13. namespace ChartTest  
  14. {  
  15.     public partial class Form1 : Form  
  16.     {  
  17.         public Form1()  
  18.         {  
  19.             InitializeComponent();  
  20.         }  
  21.   
  22.         private NetworkStream networkStream;  
  23.         private StreamReader streamReader;  
  24.         private StreamWriter streamWriter;  
  25.         private TcpClient myclient;  
  26.         private Thread recvThread;   // 接收信息线程   
  27.         private Thread sendThread;   // 发送信息线程   
  28.         private Thread serverThread;// 服务线程   
  29.         private Thread st;  
  30.   
  31.         private void button1_Click(object sender, EventArgs e)  
  32.         {  
  33.             serverThread = new Thread(new ThreadStart(Connection));  
  34.             serverThread.Start();  
  35.         }  
  36.   
  37.         private void Connection()  
  38.         {  
  39.             /* 
  40.             try 
  41.             { 
  42.                 IPAddress ipAddress = IPAddress.Parse(txtIP.Text); 
  43.                 Int32 port = Int32.Parse(txtPort.Text); 
  44.                 IPEndPoint ipe = new IPEndPoint(ipAddress, port); 
  45.                 myclient = new TcpClient(); 
  46.                 myclient.Connect(ipe); 
  47.             } 
  48.             catch 
  49.             { 
  50.                 MessageBox.Show("没有连接到服务器!"); 
  51.                 return; 
  52.             } 
  53.             */  
  54.             try  
  55.             {  
  56.                 IPAddress ipAddress = IPAddress.Parse(txtIP.Text);  
  57.                 Int32 port = Int32.Parse(txtPort.Text);  
  58.                 string hostName = Dns.GetHostEntry(ipAddress).HostName;  
  59.                 myclient = new TcpClient(hostName, port);  
  60.             }  
  61.             catch  
  62.             {  
  63.                 MessageBox.Show("没有连接到服务器!");  
  64.                 return;  
  65.             }  
  66.               
  67.             listBox1.Items.Add("客户端成功连接上服务器!");  
  68.             button1.Enabled = false;     // 连接上了,不让按“连接”按钮   
  69.             button2.Enabled = true;  
  70.             button3.Enabled = true;  
  71.   
  72.             networkStream = myclient.GetStream();  
  73.             streamReader = new StreamReader(networkStream);  
  74.             streamWriter = new StreamWriter(networkStream);  
  75.             // 创建接收信息线程,并启动   
  76.             recvThread = new Thread(new ThreadStart(RecvData));  
  77.             recvThread.Start();  
  78.         }  
  79.   
  80.         // 接收数据   
  81.         private void RecvData()  
  82.         {  
  83.             string s = streamReader.ReadLine();  
  84.             // 如果没接到服务器退出的消息,则继续接收信息   
  85.             while (s!=null&&!s.Equals("exit"))  
  86.             {  
  87.                 listBox1.Items.Add("收到信息:" + s);  
  88.                 s = streamReader.ReadLine();  
  89.             }  
  90.             // 收到服务器退出的消息,释放资源   
  91.             listBox1.Items.Add("服务器关闭");  
  92.             listBox1.Items.Add("客户端关闭");  
  93.             button1.Enabled = true;  
  94.             button2.Enabled = false;  
  95.             button3.Enabled = false;  
  96.   
  97.             //      streamReader.Close();   
  98.             //      streamWriter.Close();   
  99.             //      networkStream.Close();   
  100.             //      myclient.Close();   
  101.             ReleaseResouce();  
  102.         }  
  103.   
  104.         private void button2_Click(object sender, EventArgs e)  
  105.         {  
  106.             button1.Enabled = true;  // 按了停止之后,“连接”按钮可以用,“发送”不能用   
  107.             button2.Enabled = false;  
  108.             button3.Enabled = false;  
  109.             string exitMsg = "exit";  // 要退出时,发送 exit 信息给服务器   
  110.             streamWriter.WriteLine(exitMsg);  
  111.             //刷新当前数据流中的数据   
  112.             streamWriter.Flush();  
  113.             listBox1.Items.Add("客户端关闭");  
  114.             ReleaseResouce();  
  115.         }  
  116.   
  117.         private void button3_Click(object sender, EventArgs e)  
  118.         {  
  119.             // 启动发送线程   
  120.             sendThread = new Thread(new ThreadStart(SendData));  
  121.             sendThread.Start();  
  122.         }  
  123.   
  124.         // 发送数据   
  125.         private void SendData()  
  126.         {  
  127.             // 发送信息不允许为空   
  128.             if (txtMsg.Text == "")  
  129.             {  
  130.                 MessageBox.Show("发送的信息不能为空!");  
  131.                 txtMsg.Focus();  
  132.                 return;  
  133.             }  
  134.             try  
  135.             {  
  136.                 //往当前的数据流中写入一行字符串   
  137.                 streamWriter.WriteLine(txtMsg.Text);  
  138.                 //刷新当前数据流中的数据   
  139.                 streamWriter.Flush();  
  140.                 listBox1.Items.Add("发送信息:" + txtMsg.Text);  
  141.                 txtMsg.Text = "";  // 清空   
  142.             }  
  143.             catch (Exception exc)  
  144.             {  
  145.                 MessageBox.Show(exc.Message, "ClientClient提示");  
  146.             }  
  147.         }  
  148.   
  149.         private void Form1_Load(object sender, EventArgs e)  
  150.         {  
  151.             // 在未连接服务器前,不能发送信息和停止   
  152.             button2.Enabled = false;  
  153.             button3.Enabled = false;  
  154.         }  
  155.   
  156.   
  157.         // 释放资源   
  158.         private void ReleaseResouce()  
  159.         {  
  160.             networkStream.Close();  
  161.             streamReader.Close();  
  162.             streamWriter.Close();  
  163.             if (sendThread!=null&&sendThread.IsAlive)  
  164.             {  
  165.                 sendThread.Abort();  
  166.             }  
  167.             if (recvThread.IsAlive)  
  168.             {  
  169.                 recvThread.Abort();  
  170.             }  
  171.             if (serverThread.IsAlive)  
  172.             {  
  173.                 serverThread.Abort();  
  174.             }  
  175.             myclient.Close();  
  176.         }  
  177.   
  178.         private void Form1_FormClosing(object sender, FormClosingEventArgs e)  
  179.         {  
  180.             // 如果是在连接中,则不允许关闭窗口   
  181.             if (button1.Enabled == false)  
  182.             {  
  183.                 MessageBox.Show("请先停止连接!", "ClientClient提示");  
  184.                 e.Cancel = true;  
  185.             }  
  186.         }  
  187.   
  188.         private void button4_Click(object sender, EventArgs e)  
  189.         {  
  190.             // 启动发送线程   
  191.             st = new Thread(new ThreadStart(SeData));  
  192.             st.Start();  
  193.         }  
  194.   
  195.         // 发送数据   
  196.         private void SeData()  
  197.         {  
  198.             Random r = new Random();  
  199.             for (int i = 0; i < 10000; i++)  
  200.             {  
  201.                 Thread.Sleep(400);  
  202.                 try  
  203.                 {  
  204.                     //往当前的数据流中写入一行字符串   
  205.                     streamWriter.WriteLine(r.Next(80).ToString());  
  206.                     //刷新当前数据流中的数据   
  207.                     streamWriter.Flush();  
  208.                     listBox1.Items.Add("发送信息:" + r.Next(80).ToString());  
  209.                 }  
  210.                 catch (Exception exc)  
  211.                 {  
  212.                     MessageBox.Show(exc.Message, "ClientClient提示");  
  213.                 }  
  214.             }  
  215.         }  
  216.   
  217.         private void button5_Click(object sender, EventArgs e)  
  218.         {  
  219.             st.Abort();  
  220.         }  
  221.   
  222.     }  
  223. }  
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;


namespace ChartTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private NetworkStream networkStream;
        private StreamReader streamReader;
        private StreamWriter streamWriter;
        private TcpClient myclient;
        private Thread recvThread;   // 接收信息线程
        private Thread sendThread;   // 发送信息线程
        private Thread serverThread;// 服务线程
        private Thread st;

        private void button1_Click(object sender, EventArgs e)
        {
            serverThread = new Thread(new ThreadStart(Connection));
            serverThread.Start();
        }

        private void Connection()
        {
            /*
            try
            {
                IPAddress ipAddress = IPAddress.Parse(txtIP.Text);
                Int32 port = Int32.Parse(txtPort.Text);
                IPEndPoint ipe = new IPEndPoint(ipAddress, port);
                myclient = new TcpClient();
                myclient.Connect(ipe);
            }
            catch
            {
                MessageBox.Show("没有连接到服务器!");
                return;
            }
            */
            try
            {
                IPAddress ipAddress = IPAddress.Parse(txtIP.Text);
                Int32 port = Int32.Parse(txtPort.Text);
                string hostName = Dns.GetHostEntry(ipAddress).HostName;
                myclient = new TcpClient(hostName, port);
            }
            catch
            {
                MessageBox.Show("没有连接到服务器!");
                return;
            }
            
            listBox1.Items.Add("客户端成功连接上服务器!");
            button1.Enabled = false;     // 连接上了,不让按“连接”按钮
            button2.Enabled = true;
            button3.Enabled = true;

            networkStream = myclient.GetStream();
            streamReader = new StreamReader(networkStream);
            streamWriter = new StreamWriter(networkStream);
            // 创建接收信息线程,并启动
            recvThread = new Thread(new ThreadStart(RecvData));
            recvThread.Start();
        }

        // 接收数据
        private void RecvData()
        {
            string s = streamReader.ReadLine();
            // 如果没接到服务器退出的消息,则继续接收信息
            while (s!=null&&!s.Equals("exit"))
            {
                listBox1.Items.Add("收到信息:" + s);
                s = streamReader.ReadLine();
            }
            // 收到服务器退出的消息,释放资源
            listBox1.Items.Add("服务器关闭");
            listBox1.Items.Add("客户端关闭");
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;

            //		streamReader.Close();
            //		streamWriter.Close();
            //		networkStream.Close();
            //		myclient.Close();
            ReleaseResouce();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            button1.Enabled = true;  // 按了停止之后,“连接”按钮可以用,“发送”不能用
            button2.Enabled = false;
            button3.Enabled = false;
            string exitMsg = "exit";  // 要退出时,发送 exit 信息给服务器
            streamWriter.WriteLine(exitMsg);
            //刷新当前数据流中的数据
            streamWriter.Flush();
            listBox1.Items.Add("客户端关闭");
            ReleaseResouce();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            // 启动发送线程
            sendThread = new Thread(new ThreadStart(SendData));
            sendThread.Start();
        }

        // 发送数据
        private void SendData()
        {
            // 发送信息不允许为空
            if (txtMsg.Text == "")
            {
                MessageBox.Show("发送的信息不能为空!");
                txtMsg.Focus();
                return;
            }
            try
            {
                //往当前的数据流中写入一行字符串
                streamWriter.WriteLine(txtMsg.Text);
                //刷新当前数据流中的数据
                streamWriter.Flush();
                listBox1.Items.Add("发送信息:" + txtMsg.Text);
                txtMsg.Text = "";  // 清空
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "ClientClient提示");
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 在未连接服务器前,不能发送信息和停止
            button2.Enabled = false;
            button3.Enabled = false;
        }


        // 释放资源
        private void ReleaseResouce()
        {
            networkStream.Close();
            streamReader.Close();
            streamWriter.Close();
            if (sendThread!=null&&sendThread.IsAlive)
            {
                sendThread.Abort();
            }
            if (recvThread.IsAlive)
            {
                recvThread.Abort();
            }
            if (serverThread.IsAlive)
            {
                serverThread.Abort();
            }
            myclient.Close();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 如果是在连接中,则不允许关闭窗口
            if (button1.Enabled == false)
            {
                MessageBox.Show("请先停止连接!", "ClientClient提示");
                e.Cancel = true;
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            // 启动发送线程
            st = new Thread(new ThreadStart(SeData));
            st.Start();
        }

        // 发送数据
        private void SeData()
        {
            Random r = new Random();
            for (int i = 0; i < 10000; i++)
            {
                Thread.Sleep(400);
                try
                {
                    //往当前的数据流中写入一行字符串
                    streamWriter.WriteLine(r.Next(80).ToString());
                    //刷新当前数据流中的数据
                    streamWriter.Flush();
                    listBox1.Items.Add("发送信息:" + r.Next(80).ToString());
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "ClientClient提示");
                }
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            st.Abort();
        }

    }
}
关于线程访问控件问题,为了偷懒,我直接屏蔽了,在Program.cs的Main()函数中加入:
  1. System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls =false;
  1. System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;  
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
例子源码:http://download.csdn.net/detail/wangqiuyun/4502341
原文地址:https://www.cnblogs.com/WTFly/p/5340614.html