欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 三种方式实现Socket数据接收

程序员文章站 2022-06-15 19:12:53
目录stream.read 方法将数据接收放到 while (true)stream.read 方法当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。语法:public ab...

stream.read 方法

当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。

语法:

public abstract int read(byte[] buffer, int offset, int count)

参数:

buffer : 字节数组。此方法返回时,该缓冲区包含指定的字符数组,该数组的  offset 和 ( offset +  count -1) 之间的值由从当前源中读取的字节替换。

offset buffer 中的从零开始的字节偏移量,从此处开始存储从当前流中读取的数据。

count : 要从当前流中最多读取的字节数。

返回值:

读入缓冲区中的总字节数。如果当前可用的字节数没有请求的字节数那么多,则总字节数可能小于请求的字节数,或者如果已到达流的末尾,则为零 (0)。

备注:

此方法的实现从当前流中读取最多的 count 个字节,并将它们存储在从  offset 开始的  buffer 中。流中的当前位置提升已读取的字节数;但是,如果出现异常,流中的当前位置保持不变。实现返回已读取的字节数。仅当位置当前位于流的末尾时,返回值才为零。如果没有任何可用的数据,该实现将一直阻塞到至少有一个字节的数据可读为止。仅当流中不再有其他的数据,而且也不再需要更多的数据(如已关闭的套接字或文件尾)时, read 才返回 0。 即使尚未到达流的末尾,实现仍可以随意返回少于所请求的字节。

之前一般采用如下方式进行数据接收:

int recv;//定义接收数据长度变量
            ipendpoint ipend = new ipendpoint(ipaddress.parse(textbox1.text), int.parse(textbox2.text));//接收端所监听的接口,ip也可以用ipaddress.any
            socket socket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);//初始化一个socket对象
            socket.bind(ipend);//绑定套接字到一个ip地址和一个端口上(bind());
            socket.listen(10);
            while (true)
            {
                byte[] data = new byte[1024];//对data清零
                socket clientsocket = socket.accept(); //一旦接受连接,创建一个客户端
                recv = clientsocket.receive(data);
                if (recv == 0) //如果收到的数据长度小于0,则退出
                    break;
                string stringdata = "0x" + bitconverter.tostring(data).replace("-", " 0x").tolower();
                                                                                                                  
                this.invoke((eventhandler)delegate
                {
                    richtextbox1.text += datetime.now.tostring("yy-mm-dd hh:mm:ss")  + stringdata + "\n";
                });
            }


之前用的时候没发现什么问题,但是今天在测试金属门数据接收的时候发现会丢数据,金属门每隔十秒给我一次数据,用上面这个差不多60秒才能收到一组数据,针对以上问题,做了如下修改:

将数据接收放到 while (true)

将数据接收放到 while (true),数据接收正常

以下分别采用三种方式实现了数据的正常接收,代码如下:

using system;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.diagnostics;
using system.drawing;
using system.linq;
using system.net;
using system.net.sockets;
using system.text;
using system.threading;
using system.threading.tasks;
using system.windows.forms;

namespace metalgate
{
    public partial class mainform : form
    {
        public mainform()
        {
            initializecomponent();
        }
        private backgroundworker demobgworker = new backgroundworker();
        static tcpclient tcpclient;
        static networkstream stream;
        private void mainform_load(object sender, eventargs e)
        {
            textbox1.text = "192.168.1.99";
            textbox2.text = "8234";

        }
        //private void bgworker_dowork(object sender, doworkeventargs e)
         private void bgworker_dowork()
        {
            
            var serveripendpoint = new ipendpoint(ipaddress.parse("192.168.1.99"), 8234); // 当前服务器使用的ip和端口
            tcplistener tcplistener = new tcplistener(serveripendpoint);
            tcplistener.start();
            console.writeline("服务端已启用......"); // 阻塞线程的执行,直到一个客户端连接
            tcpclient = tcplistener.accepttcpclient();
            console.writeline("已连接.");
            stream = tcpclient.getstream();          // 创建用于发送和接受数据的networkstream


            var t1 = new thread(receivemsg);
            t1.isbackground = true;
            t1.start();

        }
        private void bgworker_dowork1()
        {
            //在这里执行耗时的运算。
            int recv;//定义接收数据长度变量
            ipendpoint ipend = new ipendpoint(ipaddress.parse(textbox1.text), int.parse(textbox2.text));//接收端所监听的接口,ip也可以用ipaddress.any
            socket socket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);//初始化一个socket对象
            socket.bind(ipend);//绑定套接字到一个ip地址和一个端口上(bind());
            socket.listen(10);

            //创建监听线程
             thread thread = new thread(listen);
             thread.isbackground = true;
             thread.start(socket);

          
        }
         /// <summary>
        /// 等待客户端的连接 并且创建与之通信的socket
        /// </summary>
        socket socketsend;
        void listen(object o)
        {
            try
            {
                socket socketwatch = o as socket;
                while (true)
                {
                    socketsend = socketwatch.accept();//等待接收客户端连接                  
                    //开启一个新线程,执行接收消息方法
                    thread r_thread = new thread(received);
                    r_thread.isbackground = true;
                    r_thread.start(socketsend);
                }
            }
            catch { }
        }
        /// <summary>
         /// 服务器端不停的接收客户端发来的消息
         /// </summary>
         /// <param name="o"></param>
         void received(object o)
         {
             try
             {
                 socket socketsend = o as socket;
                 while (true)
                 {
                     //客户端连接服务器成功后,服务器接收客户端发送的消息
                     byte[] buffer = new byte[1024 * 1024 * 3];
                     //实际接收到的有效字节数
                     int len = socketsend.receive(buffer);
                     if (len == 0)
                     {
                         break;
                     }
                    // string str = encoding.utf8.getstring(buffer, 0, len);
                    string stringdata = "0x" + bitconverter.tostring(buffer, 0, len).replace("-", " 0x").tolower();
                    this.invoke((eventhandler)delegate
                        {
                            richtextbox1.text += datetime.now.tostring("yy-mm-dd hh:mm:ss -*- ") + stringdata + "\n";
                        });
                }
            }
             catch { }
         }

        private void bgworker_dowork2()
        {
            int recv;//定义接收数据长度变量
            ipendpoint ipend = new ipendpoint(ipaddress.parse(textbox1.text), int.parse(textbox2.text));//接收端所监听的接口,ip也可以用ipaddress.any
            socket socket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);//初始化一个socket对象
            socket.bind(ipend);//绑定套接字到一个ip地址和一个端口上(bind());
            socket.listen(10);
            new thread(delegate ()
            {
                socket clientsocket = null;
                while (true)
                {
                    stopwatch sw = new stopwatch();
                    // 开始计时
                    sw.start();

                    clientsocket = socket.accept(); //一旦接受连接,创建一个客户端

                    task.run(() =>
                    {
                        while (true)
                        {
                            byte[] data = new byte[50];//对data清零
                            recv = clientsocket.receive(data, 0, data.length, socketflags.none);
                            //if (recv == 0) //如果收到的数据长度小于0,则退出
                            //    break;
                            string stringdata = "0x" + bitconverter.tostring(data, 0, recv).replace("-", " 0x").tolower();

                            this.invoke((eventhandler)delegate
                            {
                                richtextbox1.text += datetime.now.tostring("yy-mm-dd hh:mm:ss -*- ") + stringdata + "\n";
                            });
                            //结束计时  
                            sw.stop();
                            long times = sw.elapsedmilliseconds;
                            this.invoke((eventhandler)delegate
                            {
                                richtextbox1.text += "执行查询总共使用了" + times + "毫秒" + "\n";
                            });
                        }
                    });
                }
            })
            { isbackground = true }.start();
        }

        void receivemsg()
        {
            byte[] buffer = new byte[1024]; // 预设最大接受1024个字节长度,可修改
            int count = 0;
            try
            {
                while ((count = stream.read(buffer, 0, buffer.length)) != 0)
                {
                    string stringdata = "0x" + bitconverter.tostring(buffer, 0, count).replace("-", " 0x").tolower();
                    console.writeline($"{tcpclient.client.localendpoint.tostring()}:{datetime.now.tostring("yy-mm-dd hh:mm:ss -*- ") + stringdata + "\n"}");
                    this.invoke((eventhandler)delegate
                    {
                        richtextbox1.text += datetime.now.tostring("yy-mm-dd hh:mm:ss -*- ") + stringdata + "\n";
                    });
                }
            }
            catch(exception ex)
            {
                console.writeline(ex.message);
            }
            
        }

            private void senddata(ipaddress remoteip, int port, byte[] bits)
        {
            //实例化socket               
            socket socket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);
            ipendpoint ipep = new ipendpoint(remoteip, port);
            socket.connect(ipep);
            //socket.send(bits, 8, socketflags.none);
            socket.send(bits);
            socket.close();
        }

        private void btnlisten_click(object sender, eventargs e)
        {
            //demobgworker.dowork += bgworker_dowork;
            //demobgworker.runworkerasync();
            //task.run(() =>
           // {
                bgworker_dowork2();
            //});
        }

        private void btnsend_click(object sender, eventargs e)
        {
            byte[] order = new byte[8];
            order = new byte[] { 0x80, 0x04, 0x00, 0x7f };
            senddata(ipaddress.parse("192.168.1.100"), int.parse("49558"), order);
            messagebox.show("指令发送成功");
        }
    }
}

C# 三种方式实现Socket数据接收

C# 三种方式实现Socket数据接收

到此这篇关于c# 三种方式实现socket数据接收的文章就介绍到这了,更多相关c# 实现socket数据接收内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!