Let's go

C#中的TCP通讯与UDP通讯

1、TCP

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

namespace Rdbclass
{
    public class Rdb
    {
        ArrayList arrDatalist = new ArrayList();//存储需要发送的数据
        ArrayList arrSendDataList = new ArrayList();//存储改变了值的数据

        private TcpClient client;//声明TCP客户端
        private ThreadStart threadStart;//声明一个线程
        private Thread client_th;
        private string sip;
        private int iPort;
        //构造函数进行数据的初始化
        public Rdb(string strip, ArrayList list, int Port)
        {
            arrDatalist = list;
            sip = strip;
            iPort = Port;
            connect_s();
        }

        //连接服务器
        private void connect_s()
        {
            try
            {
                client = new TcpClient(sip, iPort);
                threadStart = new ThreadStart(AcceptMsg);
                client_th = new Thread(threadStart);
                client_th.Start();
            }
            catch (System.Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }
        //接收数据方法,在程序运行的时候开启一个线程进行数据的接收
        private void AcceptMsg()
        {
            NetworkStream ns = client.GetStream();
            //字组处理
            while (true)
            {
                try
                {
                    byte[] bytes = new byte[4096];
                    byte[] sendBytes = new byte[4096];
                    NetworkStream sendStream1 = client.GetStream();
                    int bytesread = ns.Read(bytes, 0, bytes.Length);
                    string msg = Encoding.UTF8.GetString(bytes, 0, bytesread);
                    for (int i = 0; i < arrDatalist.Count; i++)
                    {
                        string strItemData = (string)arrDatalist[i];
                        string[] Data = strItemData.Split('|');
                        string[] DataReceive = msg.Split('|');

                        if (Data[0].ToString() == DataReceive[1].ToString() && DataReceive[0].ToString() == "val")
                        {
                            arrDatalist.RemoveAt(i);
                            string strNewData = DataReceive[1] + "|" + DataReceive[2];
                            arrDatalist.Add(strNewData);
                            sendBytes = Encoding.UTF8.GetBytes("ret|" + DataReceive[1] + "|ok!");
                            sendStream1.Write(sendBytes, 0, sendBytes.Length);
                            sendStream1.Flush();
                        }
                    }
                    ns.Flush();
                }

                catch (System.Exception ex)
                {
                    throw new Exception(ex.ToString());
                }
            }
        }

        private void Sendmessage()
        {
            if (client == null)
                return;
            NetworkStream sendStream = client.GetStream();
            Byte[] sendBytes;
            if (arrSendDataList.Count > 0)
            {
                for (int i = 0; i < arrSendDataList.Count; i++)
                {
                    string message = arrSendDataList[i].ToString();
                    arrSendDataList.RemoveAt(i);
                    sendBytes = Encoding.UTF8.GetBytes(message);
                    sendStream.Write(sendBytes, 0, sendBytes.Length);
                    sendStream.Flush();
                }
            }
        }

        //修改原始数据里面的值并发送数据
        public void ModiData(string strName, string value)
        {
            try
            {
                int iCount = arrDatalist.Count;
                if (iCount > 0)
                {
                    for (int i = 0; i < iCount; i++)
                    {
                        string strItemData = (string) arrDatalist[i];
                        string[] Data = strItemData.Split('|');
                        if (Data[0].ToString() == strName)
                        {
                            arrDatalist.RemoveAt(i);
                            string strNewData = Data[0] + "|" + value;
                            arrDatalist.Add(strNewData);
                            arrSendDataList.Add("val|" + strNewData);
                            break;
                        }
                    }
                    Sendmessage();
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }
        //退出整个应用
        public void Exit()
        {
            if (client != null)
            {
                client.Close();
            }
        }
    }
}

2、UDP

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

namespace TCPTest.PubHelp
{
    public class UPDRdc
    {
        ArrayList arrDatalist = new ArrayList();//存储点表的数据
        ArrayList arrSendDataList = new ArrayList();//存储改变了的值的数据
        private string strSendIP;//需要发送数据的地址
        private int ISendport; //发送的端口号
        IPEndPoint remoteSendIpep;
        ArrayList arrSendlist = new ArrayList();

        //11094
        /// <summary>
        /// 用于UDP发送的网络服务类
        /// </summary>
        private UdpClient udpcSend;


        public UPDRdc(ArrayList list, string SendIP, int SendPort)
        {
            arrDatalist = list;
            strSendIP = SendIP;
            ISendport = SendPort;
            StartRecvData();//初始化接收数据
        }

        //初始化发送节点
        private void SetSendPoint()
        {
            remoteSendIpep = new IPEndPoint(
                IPAddress.Parse(strSendIP), ISendport); // 发送到的IP地址和端口号
        }


        //接收数据
        /// <summary>
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartRecvData()
        {
            SetSendPoint();
            udpcSend = new UdpClient(0);
        }


        //修改原始数据里面的值并发送数据
        public void ModiData(string strName, string value)
        {
            int iCount = arrDatalist.Count;
            if (iCount > 0)
            {
                for (int i = 0; i < iCount; i++)
                {
                    string strItemData = (string)arrDatalist[i];
                    string[] Data = strItemData.Split(',');
                    if (Data[0].ToString() == strName)
                    {
                        arrDatalist.RemoveAt(i);
                        string strNewData = Data[0] + "," + value;
                        arrDatalist.Add(strNewData);
                        arrSendDataList.Add("setvardata,0;" + strNewData + ";");
                        break;
                    }
                }
                NeedSendMessage();
            }
        }


        //退出整个应用
        public void Exit()
        {
            if (udpcSend != null)
            {
                udpcSend.Close();
            }

        }

        private void NeedSendMessage()
        {
            if (arrSendDataList.Count > 0)
            {
                for (int i = 0; i < arrSendDataList.Count; i++)
                {
                    string message = arrSendDataList[i].ToString();
                    arrSendDataList.RemoveAt(i);
                    Thread thrSend = new Thread(SendMessage);
                    thrSend.Start(message);
                    Thread.Sleep(100);
                }
            }

        }
        /// <summary>
        /// 发送信息
        /// </summary>
        /// <param name="obj"></param>
        private void SendMessage(object obj)
        {
            string message = (string)obj;
            byte[] sendbytes = Encoding.Default.GetBytes(message);
            GetDataSendMessage(sendbytes, sendbytes.Length, remoteSendIpep);
        }

        //发送数据
        public void GetDataSendMessage(byte[] sendbytes, int len, IPEndPoint remoteSendIpep)
        {
            udpcSend.Send(sendbytes, len, remoteSendIpep);
        }

        //接收数据
        public string GetDataRevMessage(IPEndPoint remoteSendIpep)
        {
            IPEndPoint remoteSendIpep1 = new IPEndPoint(
                IPAddress.Parse(strSendIP), 0);
            byte[] bytRecv = udpcSend.Receive(ref remoteSendIpep);
            string message = Encoding.Default.GetString(
                bytRecv, 0, bytRecv.Length);
            return message;
        }

        public void SendCZTest(string message)
        {
            Thread thrSend = new Thread(SendMessage);
            thrSend.Start(message);
            Thread.Sleep(100);
        }
    }
}

测试:

ArrayList arrDatalist =new ArrayList();
string strSendIP = "192.168.6.135";
int ISendport = 8009;
UPDRdc uPDRdc = new UPDRdc(arrDatalist, strSendIP, ISendport);
uPDRdc.SendCZTest("\r\n测试试试吧!");

 

 二、TCP客户端

页面:

 

 代码:

 public partial class SocketForm : Form
    {
        private Socket mySocket = null;
        public const int TCPBufferSize = 1460;//缓存的最大数据个数
        public byte[] TCPBuffer = new byte[TCPBufferSize];//缓存数据的数组

        public SocketForm()
        {
            InitializeComponent();
        }

        private void SocketForm_Load(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 连接按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_connect_Click(object sender, EventArgs e)
        {
            if (btn_connect.Text == "连接")
            {
                //IP地址 和 端口号输入不为空
                if (string.IsNullOrEmpty(textBox1.Text) == false && string.IsNullOrEmpty(textBox2.Text) == false)
                {
                    try
                    {
                        IPAddress ipAddress = IPAddress.Parse(textBox1.Text);//获取IP地址
                        int Port = Convert.ToInt32(textBox2.Text);          //获取端口号

                        mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                        //使用 BeginConnect 异步连接
                        mySocket.BeginConnect(ipAddress, Port, new AsyncCallback(ConnectedCallback), mySocket);
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("IP地址或端口号错误!", "提示");
                    }
                }
                else
                {
                    MessageBox.Show("IP地址或端口号错误!", "提示");
                }
            }
            else
            {
                try
                {
                    btn_connect.Text = "连接";
                    mySocket.BeginDisconnect(false, null, null);//断开连接
                }
                catch (Exception) { }
            }
        }
        /// <summary>
        /// 连接异步回调函数
        /// </summary>
        /// <param name="ar"></param>
        void ConnectedCallback(IAsyncResult ar)
        {
            Socket socket = (Socket)ar.AsyncState;
            try
            {
                socket.EndConnect(ar);

                //设置异步读取数据,接收的数据缓存到TCPBuffer,接收完成跳转ReadCallback函数
                socket.BeginReceive(TCPBuffer, 0, TCPBufferSize, 0, new AsyncCallback(ReadCallback), socket);

                Invoke((new Action(() =>
                {
                    txt_dataRecept.AppendText("成功连接服务器\n");//对话框追加显示数据
                    btn_connect.Text = "断开";
                })));
            }
            catch (Exception e)
            {
                Invoke((new Action(() =>
                {
                    txt_dataRecept.AppendText("连接失败:" + e.ToString());//对话框追加显示数据
                })));
            }
        }
        /// <接收到数据回调函数>
        /// 
        /// </summary>
        /// <param name="ar"></param>
        void ReadCallback(IAsyncResult ar)
        {
            Socket socket = (Socket)ar.AsyncState;//获取链接的Socket
            int CanReadLen = socket.EndReceive(ar);//结束异步读取回调,获取读取的数据个数

            if (CanReadLen > 0)
            {
                string str = Encoding.Default.GetString(TCPBuffer, 0, CanReadLen);//Byte值根据ASCII码表转为 String
                Invoke((new Action(() => //C# 3.0以后代替委托的新方法
                {
                    if (checkBox1.Checked)//16进制显示
                    {
                        txt_dataRecept.AppendText(byteToHexStr(TCPBuffer, CanReadLen));//对话框追加显示数据
                    }
                    else
                    {
                        txt_dataRecept.AppendText(Encoding.Default.GetString(TCPBuffer, 0, CanReadLen));//对话框追加显示数据
                    }
                })));

                //设置异步读取数据,接收的数据缓存到TCPBuffer,接收完成跳转ReadCallback函数
                socket.BeginReceive(TCPBuffer, 0, TCPBufferSize, 0, new AsyncCallback(ReadCallback), socket);
            }
            else//异常
            {
                Invoke((new Action(() => //C# 3.0以后代替委托的新方法
                {
                    btn_connect.Text = "连接";
                    txt_dataRecept.AppendText("\n异常断开\n");//对话框追加显示数据
                })));
                try
                {
                    mySocket.BeginDisconnect(false, null, null);//断开连接
                }
                catch (Exception) { }
            }
        }
        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_send_Click(object sender, EventArgs e)
        {
            String Str = txt_dataSend.Text.ToString();//获取发送文本框里面的数据
            try
            {
                if (Str.Length > 0)
                {
                    if (checkBox2.Checked)//选择16进制发送
                    {
                        byte[] byteHex = strToToHexByte(Str);
                        mySocket.BeginSend(byteHex, 0, byteHex.Length, 0, null, null); //发送数据
                    }
                    else
                    {
                        byte[] byteArray = Encoding.Default.GetBytes(Str);//Str 转为 Byte值
                        mySocket.BeginSend(byteArray, 0, byteArray.Length, 0, null, null); //发送数据
                    }
                }
            }
            catch (Exception) { }
        }
        /// <summary>
        /// 清除接收
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_clearAccept_Click(object sender, EventArgs e)
        {
            txt_dataRecept.Clear();
        }
        /// <summary>
        /// 清除发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_clearSend_Click(object sender, EventArgs e)
        {
            txt_dataSend.Clear();
        }

        #region 进制转换
        /// <字节数组转16进制字符串>
        /// <param name="bytes"></param>
        /// <returns> String 16进制显示形式</returns>
        public static string byteToHexStr(byte[] bytes,int Len)
        {
            string returnStr = "";
            try
            {
                if (bytes != null)
                {
                    for (int i = 0; i < Len; i++)
                    {
                        returnStr += bytes[i].ToString("X2");
                        returnStr += " ";//两个16进制用空格隔开,方便看数据
                    }
                }
                return returnStr;
            }
            catch (Exception)
            {
                return returnStr;
            }
        }
        /// <字符串转16进制格式,不够自动前面补零>
        /// 
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        private static byte[] strToToHexByte(String hexString)
        {
            int i;
            hexString = hexString.Replace(" ", "");//清除空格
            if ((hexString.Length % 2) != 0)//奇数个
            {
                byte[] returnBytes = new byte[(hexString.Length + 1) / 2];
                try
                {
                    for (i = 0; i < (hexString.Length - 1) / 2; i++)
                    {
                        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
                    }
                    returnBytes[returnBytes.Length - 1] = Convert.ToByte(hexString.Substring(hexString.Length - 1, 1).PadLeft(2, '0'), 16);
                }
                catch
                {
                    MessageBox.Show("含有非16进制字符", "提示");
                    return null;
                }
                return returnBytes;
            }
            else
            {
                byte[] returnBytes = new byte[(hexString.Length) / 2];
                try
                {
                    for (i = 0; i < returnBytes.Length; i++)
                    {
                        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
                    }
                }
                catch
                {
                    MessageBox.Show("含有非16进制字符", "提示");
                    return null;
                }
                return returnBytes;
            }
        }
        #endregion

       
    }
View Code

测试结果:

 

 

 

 

转载:https://www.cnblogs.com/wustjz/p/4650965.html

 

posted @ 2020-12-07 16:10  chenze  阅读(503)  评论(0编辑  收藏  举报
有事您Q我