广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C# 三种方式实现Socket数据接收
  • 361
分享到

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

2024-04-02 19:04:59 361人浏览 八月长安
摘要

目录Stream.Read 方法将数据接收放到 while (true)Stream.Read 方法 当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。 语

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数据接收内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C# 三种方式实现Socket数据接收

本文链接: https://www.lsjlt.com/news/154648.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C# 三种方式实现Socket数据接收
    目录Stream.Read 方法将数据接收放到 while (true)Stream.Read 方法 当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。 语...
    99+
    2022-11-12
  • C# Socket数据接收的三种实现方式
    Stream.Read 方法 当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。 语法: public abstract int Read(byt...
    99+
    2022-11-13
  • Java后端之俯瞰数据接收的三种方式
    目录一、前言二、正文部分第一种方法:第二种方法:第三种方法:三种方法概览图:一、前言 前面我们说了一些网页表单的功能,现在我们先来讲解数据的传输,如何进行前后端的联系 (建议先看完上...
    99+
    2022-11-12
  • PHP连接MySQL数据库三种实现方法
    引言 PHP与MySQL的连接有三种API接口,分别是:PHP的MySQL扩展 、PHP的mysqli扩展 、PHP数据对象(PDO) ,下面针对以上三种连接方式做下总结,以备在不同场景下选出最优方案。 PHP的...
    99+
    2022-05-23
    PHP 连接 MySQL 数据库
  • C#多态的三种实现方式(小结)
    C#实现多态主要有3种方法,虚方法,抽象类,接口 1 虚方法 在父类的方法前面加关键字virtual, 子类重写该方法时在方法名前面加上override关键字,例如下面的Perso...
    99+
    2022-11-11
  • MySQL数据库的两种连接方式:TCP/IP和Socket
    Linux平台环境下主要有两种连接方式,一种是TCP/IP连接方式,另一种就是socket连接。 在Windows平台下,有name pipe和share memory(不考虑)两种。 TCP/IP连接是网络中用得最多的一种方式...
    99+
    2017-12-06
    MySQL数据库的两种连接方式:TCP/IP和Socket
  • PHP命令行脚本接收传入参数的三种方式
    目录 一、使用`$argv`和`$argc`参数接收二、使用`getopt`函数(推荐使用这种方法)三、提示用户输入 通常PHP都做http方式请求了,可以使用GET、POST…方式接收参...
    99+
    2023-09-30
    php 开发语言
  • C#实现套接字发送接收数据
    本文实例为大家分享了C#实现套接字发送接收数据的具体代码,供大家参考,具体内容如下 服务端 namespace TestServer { public partial ...
    99+
    2022-11-12
  • C++中strlen函数的三种实现方法
    目录一、strlen函数是什么二、strlen的三种实现方法1、第一种方法(直接)2、第二种方法(递归)3、第三种方法(指针-指针)四、小结一、strlen函数是什么 我们经常用到s...
    99+
    2022-11-13
  • 浅谈Java 三种方式实现接口校验
    本文介绍了Java 三种方式实现接口校验,主要包括AOP,MVC拦截器,分享给大家,具体如下:方法一:AOP代码如下定义一个权限注解package com.thinkgem.jeesite.common.annotation; impor...
    99+
    2023-05-30
    java 接口 校验
  • SpringMVC接收java.util.Date类型数据的2种方式小结
    SpringMVC接收java.util.Date类型数据 在Controller中如下定义方法 public PassQueryRequest trade(@ModelAttr...
    99+
    2022-11-12
  • C#如何实现套接字发送接收数据
    这篇文章主要介绍了C#如何实现套接字发送接收数据,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下服务端namespace TestServer{ ...
    99+
    2023-06-21
  • C# 实现Eval(字符串表达式)的三种方法
    目录一、背景二、代码三、测试一、背景 假如给定一个字符串表达式"-12 * ( - 2.2 + 7.7 ) - 44 * 2",让你计算结果,熟悉JavaScript的都知道有个E...
    99+
    2022-11-12
  • SpringBoot调用第三方WebService接口的两种实现方式
    WebService简介 WebService接口的发布通常一般都是使用WSDL(web service descriptive language)文件的样式来发布的,该文档包含了请求的参数信息,返回...
    99+
    2023-09-12
    spring boot java 后端
  • Python实现列表拼接和去重的三种方式
    目录列表拼接三种方式 方式一:简简单单的“+” 方法二:切片赋值 方式三:列表自带的extend() 列表去重的三种方式 利用集合set的特性 利用字典key的不可重复属性 利用in...
    99+
    2022-11-12
  • 一文详解PHP连接MySQL数据库的三种方式
    目录1.MySQL扩展2.mysqli扩展3.PDO扩展知识点补充PHP与MySQL的连接有三种API接口,分别是:PHP的MySQL扩展 、PHP的mysqli扩展 、PHP数据对...
    99+
    2022-11-13
  • C#实现Socket服务器及多客户端连接的方式
    服务端代码[控制台示例] static List<Socket> Sockets = new List<Socket>(); static v...
    99+
    2022-11-13
  • python网络编程调用recv函数完整接收数据的三种方法
    最近在使用python进行网络编程开发一个通用的tcpclient测试小工具。在使用socket进行网络编程中,如何判定对端发送一条报文是否接收完成,是进行socket网络开发必须要考虑的一个问题。这里,简...
    99+
    2022-06-04
    三种 函数 网络编程
  • docker容器间进行数据共享的三种实现方式
    目录一、Bind Mounts方式共享数据二、Volumes方式数据共享三、Volume container(数据卷容器)方式3.1.创建数据卷容器3.2.使用数据卷容器我们本节为大...
    99+
    2022-11-13
  • C语言函数调用的三种实现方法实例
    目录C语言函数第一种方法第二种方法第三种方法总结C语言函数 1.概念:函数是一组一起执行一个任务的语句,每个c程序都必须有一个main函数,程序员可以把代码划分到不同的函数当中去,在...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作