C#建立TCP(源码带注释)

打开服务器和客户端如下图所示:

 

单击“开始监听”

单击“链接服务器”

单击客户端“发送消息”,服务器端收到消息

建立链接,进行数据传输

 

断开链接,停止监听

 

代码完美注释如下:

//客户端程序

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.Net;
using System.Threading;


namespace Client1
{
    /// <summary>
    /// 一般情况下,执行任务采用多线程,可避免假死现象;
    /// 跨线程间更新窗体,需要使用回调(委托);
    /// 回调(委托)的使用:定义,声明,实例化;
    /// 回调(委托)实例化后,使用时采用 Invoke(实例化,参数)方法,
    /// 定义的写法,要采用容易辨认的方式,可提高程序的可读性;
    /// 创建线程后,需要开启线程;
    /// </summary>
    public partial class frmClient : Form
    {
        private TcpClient myTcpClient;//定义TCP客户端
        private NetworkStream mynetworkstream;//网络数据流
        private Thread myReceiveMsgThread;//创建接收消息线程

        //定义回调(委托),用以完成显示接收到的数据
        private delegate void ShowReceiveMsgCallBack(string text);
        ShowReceiveMsgCallBack showReceiveMsgCallBack;//声明回调
        //定义回调(委托),用以完成显示进度条
        private delegate void ShowProgressBarCallBack();
        ShowProgressBarCallBack showProgressBarCallBack;//声明回调
        //定义委托(回调),用以完成状态lab的显示
        private delegate void ShowLabStateCallBack(string str);
        ShowLabStateCallBack showLabStateCallBack;//声明回调

        public frmClient()
        {
            InitializeComponent();
        }

        private void btn_StartConnect_Click(object sender, EventArgs e)
        {
            //创建并实例化IP终结点
            IPAddress addr = IPAddress.Parse(txt_ServerIP.Text);
            int port=Convert.ToInt32(txt_ServerPort.Text);
            IPEndPoint ipEndPoint = new IPEndPoint (addr,port);
            //实例化客户端
            myTcpClient = new TcpClient();
            //为了避免异常
            try
            {
                //发起TCP链接
                myTcpClient.Connect(ipEndPoint);
                if (myTcpClient != null)
                    lab_state.Text = "服务器已连接!";
                //绑定网络数据流
                mynetworkstream = myTcpClient.GetStream();
                //创建接收信息线程
                myReceiveMsgThread = new Thread(ReceiveMsg);
                //开启线程
                myReceiveMsgThread.Start();

            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
                lab_state.Text = "服务器链接失败!";
            }
        }
        //创建一个方法,接收消息
        private void ReceiveMsg()
        {
            while (true)
            {
                try
                {
                    //获取数据
                    byte[] getData=new byte[1024];          //创建一个数组来存储接收到的数据
                    mynetworkstream.Read(getData,0,getData.Length);//将接收到的数据放到数组中
                    //转换为字符串
                    string msg = Encoding.Default.GetString(getData);
                    //将受到的信息添加到列表中
                    lst_Receive.Invoke(showReceiveMsgCallBack, msg);
                    //修改状态指示,因为是跨线程的,所以使用回调(委托)
                    lab_state.Invoke(showLabStateCallBack,"数据接收中……"); ;
                    //修改进度条的值
                    pgb_Client.Invoke(showProgressBarCallBack);

                }
                catch(ThreadAbortException)
                {
                    //无操作,用来响应人为抛出的异常;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);//抛出异常的信息
                    if (mynetworkstream != null)//有可能网络数据流还没有建立
                        mynetworkstream.Dispose();
                    break;//当抛出异常后,需要break一下,才能终结;

                }
            }
        }
        //添加接收消息到列表框的被委托的方法
        private void AddMsgToList(string text)
        {
            lst_Receive.Items.Add(text);
        }
        //初始化
        private void frmClient_Load(object sender, EventArgs e)
        {
            //实例化委托(回调)
            showReceiveMsgCallBack = new ShowReceiveMsgCallBack(AddMsgToList);
            showProgressBarCallBack = new ShowProgressBarCallBack(ChangePgb);
            showLabStateCallBack = new ShowLabStateCallBack(ShowLabState);
        }
        //发送消息按钮单击事件
        private void btn_SendMsg_Click(object sender, EventArgs e)
        {
            byte[] sendData;//定义发送数组
            //将数组进行字节编码,以便能够发送
            sendData = Encoding.Default.GetBytes(txt_SendMsg.Text);
            //发送,写入网络数据流中,括号中依次是:发送的数组,发送的开始位置,发送数据的长度
            mynetworkstream.Write(sendData,0,sendData.Length);
     
        }
        //端口连接按钮单击事件
        private void btn_StopConnect_Click(object sender, EventArgs e)
        {
            //销毁TCP客户端和网络数据流的实例
            myTcpClient.Close();
            mynetworkstream.Dispose();
            myReceiveMsgThread.Abort();//结束进程
            lab_state.Text = "服务器已断开!";
        }
        //用来改变进度条状态被委托的方法
        private void ChangePgb()
        {
            //划分十个部分,每发一个增加1
            if (pgb_Client.Value < pgb_Client.Maximum)
                pgb_Client.Value++;
            else
                pgb_Client.Value = 0;
        }
        //用来显示lab状态被委托的方法
        private void ShowLabState(string str)
        {
            lab_state.Text = str;
        }
    }
}

 

//服务器程序

 

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.Net;
using System.Threading;

 


namespace Server1
{
    public partial class frmServer : Form
    {
        //定义委托(回调),用来显示接收的数据
        private delegate void ShowMsgCallBack(string str);
        ShowMsgCallBack showMsgCallBack;
        //定义委托(回调),用来显示状态信息
        private delegate void ShowLabStateCallBack(string str);
        ShowLabStateCallBack showLabStateCallBack;

 

        TcpListener myTcpListener;//TCP监听器
        TcpClient mytcpClient;     //客户端
        private Thread AcceptTcpClientThread;//接收链接线程
        private NetworkStream mynetworkStream;//网络数据流

 

        public frmServer()
        {
            InitializeComponent();
        }

 

        private void btn_StartListen_Click(object sender, EventArgs e)
        {
            try
            {
                //获得IP和port
                IPAddress addr = IPAddress.Parse(txt_ServerIP.Text);
                int port = Convert.ToInt32(txt_ServerPort.Text);
                IPEndPoint ipEndPoint = new IPEndPoint(addr, port);//获得IP终结点
                myTcpListener = new TcpListener(ipEndPoint);//实例化
                myTcpListener.Start();//开始监听
                //创建并开启接收线程
                if (myTcpListener != null)
                {
                    lab_state.Text = "开始监听……";
                }
                AcceptTcpClientThread = new Thread(AcceptTcpClient);
                AcceptTcpClientThread.Start();//开启线程
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
                lab_state.Text = "监听失败!";
            }
        }
        private void AcceptTcpClient()
        {
            try
            {
                //接收客户端
                mytcpClient = myTcpListener.AcceptTcpClient();

 

                if (mytcpClient != null)
                {
                    lab_state.Invoke(showLabStateCallBack,"监听已建立……");
                }
                mynetworkStream = mytcpClient.GetStream();
                if(mynetworkStream!=null)
                {
                    lab_state.Invoke(showLabStateCallBack,"网络数据流已绑定,监听中……");
                }

 

                //循环接收数据
                while(true)
                {
                    int readlen = mytcpClient.Available;
                    if (readlen > 0)
                    {
                        byte[] getData=new byte[1024];
                        mynetworkStream.Read(getData,0,getData.Length);
                        string msg = Encoding.Default.GetString(getData);
                        lst_Receive.Invoke(showMsgCallBack,msg);

 

                        Thread.Sleep(2000);
                        mynetworkStream.Write(getData,0,getData.Length);
                    }
                }

 

            }
            catch(ThreadAbortException)     //人为中断
            {

 

            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
                if (mynetworkStream != null)
                    mynetworkStream.Dispose();
                if (myTcpListener != null)
                    mytcpClient.Close();

 

            }
        }

 

        private void frmServer_Load(object sender, EventArgs e)
        {
            showMsgCallBack = new ShowMsgCallBack(ShowMsg);//实例化
            showLabStateCallBack = new ShowLabStateCallBack(ShowLabState);
        }
        private void ShowMsg(string str)
        {
            lst_Receive.Items.Add(str);
        }
        //停止监听按钮被单击事件
        private void btn_StopListen_Click(object sender, EventArgs e)
        {

 

            myTcpListener.Stop();//停止监听
            AcceptTcpClientThread.Abort();//抛出终止,中断线程
            lab_state.Text = "停止监听";

 

        }
        private void ShowLabState(string str)
        {
            lab_state.Text = str;
        }
    }
}

 

posted @ 2013-04-20 23:18  在路上的人  阅读(2665)  评论(0)    收藏  举报