C#: socket同步通讯与异步通讯

1. socket同步通讯:

            Socket m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            m_socket.Connect(m_ipEnd);
            m_socket.Send(buf_send, (int)m_len, SocketFlags.None);
            m_socket.Receive(buf_recv, (int)m_len, SocketFlags.None);
            m_socket.Close();

2. socket异步通讯

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.Collections;

 namespace WinSocketAsync
{
    public partial class FormMain : Form
    {
        public Socket m_socket;
        public IPEndPoint m_iep;
        Queue m_qSend = new Queue();
        Queue m_qRecv = new Queue();

        int m_interval;         //发送间隔
        int m_DataLen;          //数据长度
        ulong m_curSendCount;   //当前发送次数
        ulong m_curRecvCount;   //当前接收次数
        ulong m_curSendBit;     //当前发送位数
        ulong m_curRecvBit;     //当前接收位数
        ulong m_curRightBit;    //当前正确位数
        ulong m_curErrorBit;    //当前错误位数
        byte[][] m_senddata;     //发送的数据包

        delegate void DGTextBox(string str);
        delegate void DGButton(bool b);

        public class StateObject : Object
        {
            public Socket socket;
            public byte[] buffer;
        }

        public FormMain()
        {
            InitializeComponent();
            //m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName. )
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            TCurTime_Tick(sender, e);

            m_interval = int.Parse(TBinterval.Text.Trim());
            m_DataLen = int.Parse(TBDataLen.Text.Trim());

            m_senddata = new byte[256][];
            Random rd = new Random();
            for (int i = 0; i < 256; i++)
            {
                m_senddata[i] = new byte[m_DataLen];
                for (int j = 0; j < m_DataLen; j++)
                {
                    m_senddata[i][j] = (byte)rd.Next(1, 255);
                }
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (m_socket == null)
            {
                return;
            }

            if (m_socket.Connected)
            {
                m_socket.Shutdown(SocketShutdown.Receive);
                m_socket.Close();
            }
        }

        private void TBinterval_TextChanged(object sender, EventArgs e)
        {
            int interval;
            try
            {
                interval = int.Parse(TBinterval.Text);
            }
            catch
            {
                MessageBox.Show("输入的数据格式不正确!");
                TBinterval.Text = "100";
                return;
            }

            if (interval > 1000)
            {
                MessageBox.Show(TBinterval.Text + "ms发一次,你打算明年发完吗?");
                TBinterval.Text = "100";
                return;
            }

            if (interval <= 0)
            {
                MessageBox.Show("数据长度不能小于0字节");
                TBinterval.Text = "100";
                return;
            }

            m_interval = interval;
        }

        private void TCurTime_Tick(object sender, EventArgs e)
        {
            TBCurTime.Text = DateTime.Now.ToString();
        }

        private void TSLink_Click(object sender, EventArgs e)
        {
            FormLink fl = new FormLink();
            fl.formMain = this;
            fl.ShowDialog();
        }

        public void LinkServer()
        {
            m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //m_socket.SendTimeout = 200;
            //m_socket.ReceiveTimeout = 200;
            //m_socket.Blocking = true;
            m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 200);//设置超时
            m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 200);

            m_socket.BeginConnect(m_iep, new AsyncCallback(Connect), m_socket);
        }

        public void Connect(IAsyncResult ar)
        {
            Socket socket = (Socket)ar.AsyncState;
            
            if (!socket.Connected)
            {
                MessageBox.Show("连接不到主机");
                return;
            }

            BTStart.Invoke(new DGButton(ButtonEnable), (object)true);

            StateObject sone = new StateObject();
            sone.buffer = new byte[m_DataLen];
            sone.socket = socket;
            socket.BeginReceive(sone.buffer, 0, sone.buffer.Length, 0, new AsyncCallback(Receive), sone);

            socket.EndConnect(ar);
        }

        void ButtonEnable(bool b)
        {
            BTStart.Enabled = b;
        }

        void TBSendText(string str)
        {
            TBSend.Text += str + "\r\n";
        }

        void TBRecvText(string str)
        {
            TBRecv.Text += str + "\r\n";
        }

        void TBSendTextClear(string str)
        {
            TBSend.Text ="";
        }

        void TBRecvTextClear(string str)
        {
            TBRecv.Text = "";
        }

        void TBCurSendText(string str)
        {
            TBCurSend.Text = str;
        }

        void TBCurSendBitText(string str)
        {
            TBCurSendBit.Text = str;
        }

        void TBCurRecvText(string str)
        {
            TBCurRecv.Text = str;
        }

        void TBCurRecvBitText(string str)
        {
            TBCurRecvBit.Text = str;
        }

        void Send(IAsyncResult ar)
        {
            StateObject so = (StateObject)ar.AsyncState;
            byte[] sendData = so.buffer;
            Socket socket = so.socket;

            if (socket == null)
            {
                return;
            }

            m_qSend.Enqueue(sendData);

            m_curSendCount++;
            m_curSendBit += (ulong)m_DataLen * 8;

            string sCurSendBit = m_curSendCount.ToString() + "*" + m_DataLen.ToString() + "*8" + "=" + m_curSendBit.ToString();
            TBCurSend.Invoke(new DGTextBox(TBCurSendText), (object)m_curSendCount.ToString());
            TBCurSendBit.Invoke(new DGTextBox(TBCurSendBitText), (object)sCurSendBit);
            
            string str_send = "第" + m_curSendCount.ToString() + "发送:\r\n";
            for (int i = 0; i <= m_DataLen - 1; i++)
            {
                str_send += sendData[i].ToString("X");
            }

            TBSend.Invoke(new DGTextBox(TBSendText), (object)str_send);

            if (m_curSendCount % 100 == 0)
            {
                TBSend.Invoke(new DGTextBox(TBSendTextClear), (object)"");
            }

            if (socket.Connected)
            {
                socket.EndSend(ar);
            }
            
        }

        void Receive(IAsyncResult ar)
        {
            StateObject so = (StateObject)ar.AsyncState;
            byte[] recvData = so.buffer;
            Socket socket = so.socket;

            if (socket == null)
            {
                return;
            }

            m_qRecv.Enqueue(recvData);

            m_curRecvCount++;
            m_curRecvBit += (ulong)m_DataLen * 8;

            string sCurRecvBit = m_curRecvCount.ToString() + "*" + m_DataLen.ToString() + "*8" + "=" + m_curRecvBit.ToString();
            TBCurRecv.Invoke(new DGTextBox(TBCurRecvText), (object)m_curRecvCount.ToString());
            TBCurRecvBit.Invoke(new DGTextBox(TBCurRecvBitText), (object)sCurRecvBit);

            string str_recv = "第" + m_curRecvCount.ToString() + "接收:\r\n";
            for (int i = 0; i <= m_DataLen - 1; i++)
            {
                str_recv += recvData[i].ToString("X");
            }

            TBRecv.Invoke(new DGTextBox(TBRecvText), (object)str_recv);

            if (m_curRecvCount % 100 == 0)
            {
                TBRecv.Invoke(new DGTextBox(TBRecvTextClear), (object)"");
            }

            if (m_socket.Connected)
            {
                int iRecv = socket.EndReceive(ar);
            }

            StateObject recv = new StateObject();
            recv.socket = so.socket;
            recv.buffer = new byte[m_DataLen];
            if (socket.Connected)
            {
                socket.BeginReceive(recv.buffer, 0, recv.buffer.Length, 0, new AsyncCallback(Receive), recv);
            }
        }

        private void TSend_Tick(object sender, EventArgs e)
        {
            if (m_curSendCount > m_curRecvCount)
            {
                return;
            }

            StateObject send = new StateObject();
            send.socket = m_socket;
            send.buffer = m_senddata[(byte)m_curSendCount];
            try
            {
                if (m_socket.Connected)
                {
                    m_socket.BeginSend(send.buffer, 0, send.buffer.Length, SocketFlags.None, new AsyncCallback(Send), send);
                }
            }
            catch //(System.Exception ex)
            {
                //int i = 0;
            }
            
        }

        private void BTStart_Click(object sender, EventArgs e)
        {
            BTStart.Enabled = false;
            BTEnd.Enabled = true;
            BTPause.Enabled = true;
            TBDataLen.Enabled = false;
            TBinterval.Enabled = false;

            TBStartTime.Text = DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString();
            TBEndTime.Text = "";

            m_curSendCount = 0;
            m_curRecvCount = 0;
            m_curSendBit = 0;
            m_curRecvBit = 0;
            m_curRightBit = 0;
            m_curErrorBit = 0;

            TBSend.Text = "";
            TBRecv.Text = "";

            TBCurSend.Text = m_curSendCount.ToString();
            TBCurRecv.Text = m_curRecvCount.ToString();
            TBCurSendBit.Text = m_curSendBit.ToString();
            TBCurRecvBit.Text = m_curRecvBit.ToString();
            TBRight.Text = m_curRightBit.ToString();
            TBError.Text = m_curErrorBit.ToString();

            TSend.Interval = m_interval;
            TSend.Enabled = true;

            TRate.Interval = (int)(m_interval * 0.8);

            StateObject send = new StateObject();
            send.socket = m_socket;
            send.buffer = m_senddata[(byte)m_curSendCount];

            if (m_socket.Connected)
            {
                m_socket.BeginSend(send.buffer, 0, send.buffer.Length, SocketFlags.None, new AsyncCallback(Send), send);
            }
        }

        private void BTPause_Click(object sender, EventArgs e)
        {
            if (TSend.Enabled)
            {
                BTPause.Text = "继续测试";
                TSend.Enabled = false;
            }
            else
            {
                BTPause.Text = "暂停测试";
                TSend.Enabled = true;
            }
        }

        private void BTEnd_Click(object sender, EventArgs e)
        {
            BTStart.Enabled = true;
            BTPause.Enabled = false;
            BTEnd.Enabled = false;

            TBinterval.Enabled = true;
            TBDataLen.Enabled = true;

            TSend.Enabled = false;

            TBEndTime.Text = DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString();

            TBCurSend.Text = m_curSendCount.ToString();
            TBCurRecv.Text = m_curRecvCount.ToString();
            TBCurSendBit.Text = m_curSendCount.ToString() + "*" + m_DataLen.ToString() + "*8" + "=" + m_curSendBit.ToString();
            TBCurRecvBit.Text = m_curRecvCount.ToString() + "*" + m_DataLen.ToString() + "*8" + "=" + m_curRecvBit.ToString();
            TBRight.Text = m_curRightBit.ToString();
            TBError.Text = m_curErrorBit.ToString();
        }

        void TBErrorText(string str)
        {
            TBError.Text = str;
        }

        void TBRightText(string str)
        {
            TBRight.Text = str;
        }

        void TBErrorRateText(string str)
        {
            TBErrorRate.Text = str;
        }

        private void ErrRate()
        {
            if (m_qSend.Count == 0 || m_qRecv.Count == 0)
            {
                return;
            }

            byte[] sendData = (byte[])m_qSend.Dequeue();
            byte[] recvData = (byte[])m_qRecv.Dequeue();

            for (int i = 0; i <= m_DataLen - 1; i++)
            {
                if (sendData[i] == recvData[i])
                {
                    m_curRightBit += 8;
                    continue;
                }

                m_curErrorBit += 8;
            }

            TBRight.Invoke(new DGTextBox(TBRightText), (object)m_curRightBit.ToString());
            TBError.Invoke(new DGTextBox(TBErrorText), (object)m_curErrorBit.ToString());

            ulong sum = m_curRightBit + m_curErrorBit;
            if (sum == 0)
            {
                sum = 1;
            }

            double rate = (float)m_curErrorBit / (float)sum * 100.0;
            TBErrorRate.Invoke(new DGTextBox(TBErrorRateText), (object)rate.ToString("0.0000"));
        }

        private void TRate_Tick(object sender, EventArgs e)
        {
            ErrRate();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值