【网络通讯】【Socket实现(二)】

Android Native层实现openssl+Socket网络通讯 Android native实现openssl+Socket 阅读详情

网络通讯系列

第五章 【网络通讯】【详细场景下的Demo示例(五)】
第四章 【网络通讯】【DotNetty实现(四)】
第三章 【网络通讯】【SuperSocket实现(三)】
第二章 【网络通讯】【Socket实现(二)】
第一章 【网络通讯】【通讯协议(一)】



前言

介绍使用Socket实现网络通讯。


一、程序设计

不依赖于第三方库,我们使用最原始的Socket来实现上位机客户端。
这一章的目的主要是为了让大家熟悉Socket通讯的原理,后面第三、第四章均是使用开源库实现,也是推荐大家在实际项目中使用的,更加高效、稳定。

要实现客户端,我们需要设计四个接口
分别是连接服务器、断连服务器、发送服务器内容、以及接收服务器内容

其中,接收服务器内容,我们不通过接口实现,而是通过事件通知,因为我们不知道什么时候服务器会发送内容,如果使用接口的话需要多开一个线程不断判断,不太好。

后续优化,在客户端中实现自动断线重连功能、解决连接不存在IP的服务器时时间过长问题(Ping功能)等等,这个会在第五章中的Demo实例中有完整解决方案资源可下载。

二、代码

public class CSocketClient
{
    private Thread? mReceiveThread = null;    //接收数据线程
    private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
    private Socket? __m_hSocket = null;     //Socket句柄
    private int mPort = 0;      //记录本客户端端口号
    private string mIP = "";    //记录本客户端IP地址

    public delegate void ReceiveDataEvent(string ip, int port, byte[] receive);
    public event ReceiveDataEvent? OnReceiveData;   //接收到内容事件通知

    /// <summary>
        /// 连接服务器
        /// </summary>
        /// <param name="hostAddress"></param>
        /// <param name="nHostPort"></param>
        /// <returns></returns>
    public bool Connect(string hostAddress, int nHostPort)
    {
        DisConnect();
        if (__m_hSocket == null)
        {
            __m_hSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //定义一个socket对象 
        }

        try
        {
            mPort = nHostPort;
            mIP = hostAddress;
            IPAddress sin_addr = IPAddress.Parse(hostAddress);
            IPEndPoint endPoint = new IPEndPoint(sin_addr, nHostPort);
            __m_hSocket.Connect(endPoint);
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex);
        }

        //开启一个新的线程不停的接收服务端发来的消息  
        mReceiveThread = new Thread(() => OnClientRecvTimer(_cancellationTokenSource.Token));
        mReceiveThread.Name = "SockReceive" + mReceiveThread.ManagedThreadId;
        mReceiveThread.Start();
        return true;
    }

    /// <summary>
        /// 发送服务器数据,字节
        /// </summary>
        /// <param name="sendBuf">要发送的数据</param>
        /// <returns>1:成功  0:失败</returns>
    public byte Send(byte[] sendBuf)
        {
            try
            {
                if (__m_hSocket == null)
                {
                    return 0;
                }

                int sendBufLen = sendBuf.Length;
                int sendRtn = __m_hSocket.Send(sendBuf, sendBufLen, SocketFlags.None);
                sendRtn = __m_hSocket.Send(sendBuf, 0, SocketFlags.None);
                return 1;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
            return 0;
        }

    /// <summary>
        /// 关闭连接
        /// </summary>
    public void DisConnect()
    {
        _cancellationTokenSource.Cancel();
        if (__m_hSocket is null)
        {
            return;
        }
        try
        {
            __m_hSocket.Shutdown(SocketShutdown.Both);
            Thread.Sleep(10);
            __m_hSocket.Close();                          //关闭连接
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex);
        }
    }

    /// <summary>
        /// 接收服务器数据线程
        /// </summary>
        /// <param name="clientSocket"></param>
    private void OnClientRecvTimer(CancellationToken token)
        {
            int recvLen = 0;
            byte[] mReceiveBufRemote = new byte[1024];
            while (!token.IsCancellationRequested)
            {
                Thread.Sleep(1);
                try
                {
                    if (__m_hSocket == null || __m_hSocket.Available <= 0)
                    {
                        continue;
                    }

                    mReceiveBufRemote = new byte[1024];
                    recvLen = __m_hSocket.Receive(mReceiveBufRemote, mReceiveBufRemote.Length, 0);      //接收数据
                    if (recvLen > 0)
                    {
                        recvLen = 0;
                        OnReceiveData?.Invoke(mIP, mPort, mReceiveBufRemote);
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex);
                    Thread.Sleep(100);
                }
            }
        }
}

芒果YOLO11改进176:2025最新顶会论文|尺度动态损失函数Scale-based Dynamic Loss,即插即用|以减少标签不准确对损失函数稳定性的影响 芒果YOLO11改进186:2025最新顶会论文|尺度动态损失函数Scale-based Dynamic Loss,即插即用|以减少标签不准确对损失函数稳定性的影响 阅读详情

相关推荐

别再踩坑了!Vue3 + Vant 手把手教你搞定飞书网页应用免登(SSO),附完整代码和重定向URL配置

本文详细介绍了如何使用Vue3和Vant实现飞书H5应用的免登(SSO)功能,包括飞书后台配置的关键细节、Vue3前端实现的最佳实践以及常见问题排查指南。特别针对重定向URL配置、安全设置和错误处理等常见陷阱提供了解决方案,并附有完整代码示例和性能优化建议。

weixin_29323551的博客 405

Unity如何实现网络通讯(二):SOCKET

强联网在我们的游戏开发中所占比重越来越大,尤其是开发MMO游戏时,更需要强联网来进行实时更新,所以我们就有了强联网的需要。 首先我们得清楚强联网的工作原理,说到强联网,我们就必须说到socket。 socket是对tcp/ip协议的封装和应用,是面向程序员的,给我们提供了操作网络的接口,但是我们也必须基本了解其工作原理: 强联网我们主要使用的是TCP和UDP,首先我们说一下TCP。 一说到

yibo798757741的博客 1680

IB网络下不同租户业务隔离方案

IB(InfiniBand)网络隔离可以在不同的通信模式下实现,其中包括 IPoIB(IP over InfiniBand)通信模式。在 IPoIB 模式下,InfiniBand 网络可以承载 IP 数据包,使得基于 IP 的应用程序能够在 InfiniBand 网络上进行通信。在这种情况下,IB 网络隔离通常指通过配置 Partition Key(PKey)来实现不同的租户或应用程序之间的网络隔离。然而,IB 网络隔离并不仅限于 IPoIB 模式。

guganly的专栏 1527

Java中实现用户之间的通讯

在Java中实现用户之间的通讯可以通过多种方式,这里我将介绍两种常见的方法:使用Socket编程和使用WebSocket。

weixin_73060959的博客 575

八大排序算法——(万字图文详解)

本篇博客将对“直接插入排序”、“希尔排序”、“直接选择排序”、“堆排序”、“冒泡排序”、“快速排序”、“归并排序”、“计数排序”进行详细的解析(算法逻辑、具体实现过程、时间复杂度、稳定性),并附以图片帮助大家更好地理解算法逻辑以及实现每个排序的参考代码。

Forward♞的博客 8076

深度学习动画实战:用MotorNerve系统5步实现自然角色交互

本文详细介绍了如何利用腾讯游戏的MotorNerve系统,通过深度学习技术5步实现自然角色动画交互。从环境搭建、基础运动控制到交互过渡和行走转向优化,该系统能显著提升游戏动画制作效率,尤其适合中小团队替代昂贵的动捕方案。重点解析了骨骼动画配置、PFNN控制器使用及Blender工作流集成等核心技术。

book8的博客 686

【C++网络编程】Socket基础:网络通讯程序入门级教程

本篇博文介绍了C++网络编程的基础知识,从Socket基础到Epoll的使用,为初学者提供了入门级的教程。读者将学习如何创建套接字、建立连接、发送和接收数据,并深入了解Epoll在高性能网络编程中的应用。

朝花夕拾 7639

Altium Designer(AD24/25)PCB编辑的几种方法介绍

本文介绍了Altium Designer(AD24/25)软件中PCB编辑的四种操作方法:1)通过菜单栏"Place→Component"激活;2)点击工具栏元器件图标;3)右键快捷菜单选择;4)快捷键P+C组合操作。建议初学者先通过菜单栏和快捷菜单熟悉操作,熟练后转为工具栏和快捷键以提高效率。文章配有操作示意图,帮助用户快速掌握PCB元器件放置技巧。

fydar的博客 943

欧姆龙TCP UDP Socket网络通讯资源文件

欧姆龙TCP UDP Socket网络通讯资源文件 去发现同类优质开源项目:https://gitcode.com/ 简介 本仓库提供了一个名为“欧姆龙TCP UDP Socket网络通讯.zip”的资源文件,该文件包含了多个与欧姆龙设备进行TCP和UDP Socket网络通讯相关的案例和工具。无论你是初学者还是有经验的开发者,这些资源都将帮助你更好地理解和实现欧姆龙设备的网络通讯功能。 资源内容...

gitblog_09732的博客 1019

【知识图谱】neo4j安装与配置_社区版_2025(附完整安装软件包)

(经历过各种版本NEO4J,遇见杂七杂八的各种问题,也看过非常多很好的教程,特此来分享一下,为大家排排坑。

知识靠谱的博客 2万+

从一个 ASIN 看透亚马逊:商品模型背后的增长飞轮

在亚马逊电商体系中,每件商品背后都有一套严密的商品建模逻辑。本篇文章以“ASIN 的一生”为线索,系统拆解了亚马逊的商品模型:从飞轮战略出发,剖析 SDP(Single Detail Page)机制如何实现标准化展示;再到 ASIN 编码、父子变体结构与 Offer 分离模型,逐层解析商品信息如何被建构、聚合与呈现。通过图解与案例,文章帮助读者理解商品建品流程、同款聚合原则、价格控制机制等核心逻辑,避免常见运营误区,是一份面向运营、产品、技术人员的实用参考指南。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 13万+

使用socket与c++进行网络通讯

使用socket与c++进行网络通讯 /** * 是否开启同步数据 * * @param paras * @param usrId * @return */ public Map<String, Object> isDataAuto(String paras, int usrId) { Map<String, Object> retMap = new HashMap<>();

qq_24790827的博客 248

AI人工智能 Agent:在仓储物流中的应用

AI人工智能 Agent:在仓储物流中的应用 1. 背景介绍 1.1 问题的由来 仓储物流行业是全球经济运行的基石之一,涉及商品的存储、运输、分拣和配送等多个环节。随着电子商务的普及和消费者对物流速度和精确性的要求不断提高,仓储物流

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 863

Socket网络通讯入门(一)

简单学习了解一下Socket网络通讯入门。提示:以下是本篇文章正文内容,下面仅供参考上面服务端和客户端的代码,只是用于简单交互示列,正式使用不会如此写法,因为阻塞性太大,正常使用会异步处理。

qq_37524903的博客 1336

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

玩转iPhone网络通讯之BSD Socket篇

转自:http://hi.baidu.com/myguru/blog/item/8fe0621e9eca49f81bd5769b.html在进行iPhone网络通讯程序的开发中,不可避免的要利用Socket套接字。iPhone提供了Socket网络编程的接口CFSocket,不过笔者更喜欢使用BSD Socket。 iPhone BSD Socket进行编程所需要的头文件基本都位于/X

zltianhen的专栏 462

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

网络通讯和socket编程

(1)基于流的方式;(2)面向连接;(3)可靠通信方式;(4)在网络情况不佳的时候尽量降低系统由于重传带来的带宽开销;(5)通信连接维护是面向的两个端点的,而不考虑中间网段和节点。为满足TCP协议的这些特点,TCP协议做了以下规定:①数据分片:在发送端对用户数据进行分片,在接收端进行重组,由TCP确定分片的大小并控制分片和重组;②到达确认ACK:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认;③超时重发:发送方在发送分片时启动超时。

imreallycrazy的专栏 202

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

VC+Socket 网络通讯示例

VC+Socket 网络通讯示例 博客分类:  Socket SocketVC++Windows  Cpp代码    VC+Socket 网络通讯示例  收藏      服务器端示例代码      #include    #include    #include       #define SERVER_SOCKET_ERROR 1

我的专栏 2357

在MES中如何通过Socket与车间设备进行网络通讯

        之前在博客中有写过关于Socket的几篇文章,所以今天就借此机会简单介绍一下之前的一些项目经验,即如何通过基于TCP协议的Socket网络编程实现与车间设备进行网络通讯。随着大家对工业4.0的憧憬,现在越来越多的制造型企业开始使用MES系统,MES系统除了一些后台的基本功能,如设备管理、生产管理、报表、品质管理以及生产排程等,还有一个重要的环节,就是对车间的硬件设备进行控制。控制的...

NC_star的博客 7835

iPhone网络通讯之BSD Socket篇

玩转iPhone网络通讯之BSD Socket篇(手把手教你iphone开发 - 基础篇)   作者:孙东风 2009-11-11(请尊重作者劳动成果,转载务必注明出处)   在进行iPhone网络通讯程序的开发中,不可避免的要利用Socket套接字。iPhone提供了Socket网络编程的接口CFSocket,不过笔者更喜欢使用BSD Socket。   iPhone BSD S

Keivin 3786

Java 实现简单Socket通信

1.网络通讯名词简介 IP:Internet Protocol,即互联网协议。IP现在通用的版本是IPv4,。地址是四个 byte 的数字,用点分开。正在实施的IPv6地址会复杂得多。每个机器都有一个IP地址。IP地址又分内网和外网地址,就像是我们的小名和官方大名。只有外网地址才能用来外网通讯 port:端口。和 IP 地址一起,可以唯一的确定一个网络连接的目的地。计算机的端口是用无符号的16个 bit 表示的,所以端口的范围是 0-65535,不能超过这个范围 Socket:套接字,就好像插座,可.

法毅的博客 1911

TCP/IP及Socket网络通讯

1.TCP/IP TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。客户端在收发数据前要使用 connect() 函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。其在网络的七层协议中所处的位置如下图: 1.1TCP数据...

u010304442的博客 917

如何基于TCP/IP协议进行MFC Socket网络通讯编程

MFC Socket简单网络通讯编程

小菜鸟IT修行路 3万+

08Socket网络通讯基础

TCP与UDP相关概念 TCP通讯 package Socket网络通讯基础08; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util....

u011807251的博客 211

MFC Socket网络通讯编程

 最近因为一个项目需要进行局域网络通讯,向工作单位的软件工程师请教了一下需要用到哪些知识,然后博主就自学了一遍windows网络通讯编程原理,然后就在网上找了一大堆例子,但实际运行效果并不佳,花了大概一周多的时间总算是把网络通讯程序给跑起来了(PS:虽然时间比较长,但对于一个新手程序员来说,算是不错的,哈哈。。。) 声明:本程序是借鉴于此博文的源码(http://blog.youkuaiyun.com/lo...

qq_38335172的博客 813

使用Peach简化Socket网络通讯协议开发

为什么80%的码农都做不了架构师?>>> ...

weixin_33918357的博客 705

【计算机网络篇|第二篇】深度解析TCP三次握手

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它在通信双方之间建立一条逻辑连接,保证数据按序到达、不丢失、不重复,并提供流量控制和拥塞控制能力。HTTP、FTP、SSH 等大量应用层协议都构建在 TCP 之上。由于 TCP 是面向连接的协议,通信双方在传输数据之前必须先建立连接,而建立连接的过程就是著名的「三次握手」。

wuzhihua66的博客 508
上一篇: 【网络通讯】【通讯协议(一)】
下一篇: 【网络通讯】【SuperSocket实现(三)】
Aflashstar
博客等级 码龄12年 205粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值