socket 基本使用异步操作

socket 概念讲解

计算机主机 都是独立的 硬件,而网络通信是 在多个主机进行通信的必要手段。
那么网络通信有什么内容,sockert又是什么。
首先 网络通信 一般来讲 分为5层 应用层-传输层-网络层-链路层-物理层
链路层-物理层 其实是 硬件方面的内容 比如 路由器网线这种
网络层 其实是对 网络协议的 规则制度 为了方便传输
真正需要 软件程序这边关注的 就是 传输层 和 应用层
传输层 就是 常用的 tcp udp 这些传输协议 提供信息传输
应用层 就是 常用的 http ftp 这种 已经准备好处理数据接收数据的协议

那么 socket 其实就是 传输层 的 底层原理
也就是说 实现传输层这个功能的 底层原理就是 socket技术 是socket 技术支持着TCP 和UDP 协议来进行传输

分类

既然传输层 有 TCP UDP 俩种
当使用TCP时,Socket通常被称为流式Socket(Stream Socket),它基于TCP协议,确保数据的可靠传输和有序性。
当使用UDP时,Socket则被称为数据报Socket(Datagram Socket),它基于UDP协议,提供了一种无连接的数据传输方式,不保证数据的可靠到达和顺序

TCP UDP 的区别

所以一般都是采用TCP 流的方式建立socket连接

角色

俩台主机进行通信连接 那么就会有 客户端 与 服务端 的角色
客户端负责请求消息 而服务端负责监听客户端的消息并进行连接
很经典的示意图片
在这里插入图片描述

具体使用相关函数
指令 描述
connect()/BeginConnect 客户端建立连接
bind() 服务端绑定
listen() 服务端监听 只负责监听 哪怕多个客户端进行连接请求
Accept/ BeginAccept 服务端建立连接 创建一个新的socket(可以理解服务端connect的)对象
Send()/BeginSend 客户端服务端进行发送消息操作
Receive/ BeginReceive 客户端服务端进行接收消息操作
close() 关闭操作
shutdown 更细颗粒度的关闭功能 它允许分别或同时关闭读取、写入或两者
异步

在程序方面 建立通信也是需要 代码实现 也就是 线程去执行这些,那么线程在发展过程中 为了 实现 不阻塞等待过程的 手段发展出来 异步,那么 相应的sockert技术也有对应的异步函数进行调用
BeginAccept()服务端异步建立连接 BeginReceive()服务端异步接收消息

在使用异步的时候 主要参数 会有 一个是回调方法 一个是 状态参数
这个状态参数怎么理解呢 就是你有一些信息需要记录当下的然后传给回调方法的,比如当前一些连接的ip信息之类的 需要传到回调方法中去,所以微软这个状态参数 就是方便你自定义对象 将你所需要的 传给回调,然后回调方法中接收一下
在这里插入图片描述
就比如这个RecvStateObject 对象自定义的 里面有些值需要用到,那么就在回调之前附上内容,回调后方法中进行使用即可
在这里插入图片描述
异步接收信息还需要注意的一点就是:异步建立连接的情况回调后 是开辟新的socket 去进行后续消息的操作的,你可以理解为 有一个人专门负责连接 连接好之后就开辟一个新的socket 由它一直进行消息管理。
所以 这就是为什么在 AcceptCallback 连接回调后要 自定义对象 比如RecvStateObject 都会有一个属性叫workSocket,就是把连接后新建立的socket 作为后续消息交互的工作者这个状态信息保留住,然后在BeginReceive以及回调中传自定义对象就是为了能一直使用它
通过测试可以看出来 下方我会给出测试代码片段
在这里插入图片描述
以下测试用例 是以 net 8.0 控制台项目创建
客户端

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

namespace Client
{
   
    class Program
    {
   
        static void Main(string[] args)
        {
   
            Client.StartClient();
            Console.Read();
        }
    }
    // 异步建立通信后 后续交互信息所使用的自定义状态对象  
    public class StateObject
    {
   
        // Client socket.  
        public Socket workSocket = null;
        // Size of receive buffer.  
        public const int BufferSize = 256;
        // Receive buffer.  
        public byte[] buffer = new byte[BufferSize];
        // Received data string.  
        public StringBuilder sb = new StringBuilder();
    }

    public class Client
    {
   
        // 端口号
        private const int port = 8848;

        // ManualResetEvent 设置线程同步
        private static ManualResetEvent connectDone =
            new ManualResetEvent(false);
        private static ManualResetEvent sendDone =
            new ManualResetEvent(false);
        private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);

        public static void StartClient()
        {
   
            
            try
            {
   
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
                Socket client = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);

                // 异步建立连接
                Console.WriteLine("客户端建立连接sockertID:" + client.Handle); //Handle 句柄你可以理解为ID
                client.BeginConnect(remoteEP,
                    new AsyncCallback(ConnectCallback), client
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值