手把手教你玩转SOCKET模型之重叠I/O篇(上)

select I/O 多路复用实现服务器聊天室功能 基本概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。IO多路复用适用如下场合:  (1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。  (2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。  (3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。  (4)如果一个服务器即 阅读详情

“身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”

                                                                                                                          ----- 题记  By PiggyXP(小猪)

前   言

  其实我首先应该道歉,因为7月份的时候曾信誓旦旦的说要写一套关于SOCKET所有模型的入门文章以及配套代码,不过没想到后天竟然被美女所迷出去度假了,刚刚回来不久。。。。。。-_-b其实那些模型的配套代码我已经基本写完了,只是没写配套文字,不过我想还是先从稍微难一点的模型写起吧,因为其他模型的入门毕竟要简单一些。

不过由于也是初学者,疏漏之处还望不吝指正。

本文凝聚着笔者心血,如要转载,请指明原作者及出处,谢谢!^_^

OK, Let’s go !  Have fun!! q^_^p

 

本文配套的示例源码下载地址

(VC.net 2003编写的多客户端MFC代码,配有详尽注释,只是简单的显示一下客户端发来的字符,稍加改进就是个聊天室了):

http://www.haha567.com/PiggyXP/OverlappedModel.rar

(unix系统,千万注意链接大小写)

非常感谢网络版的limin兄弟为我无偿提供的空间,以及在我学习过程中给我的大力帮助与支持,真的非常感谢他,感激涕零啊~~~~~T_T

也欢迎大家光临他的Blog一起讨论网络技术

http://blog.haha567.com/

 

(本文假设你已经具备用SOCKET简单模型编程的能力,如果对SOCKET一无所知请关注本系列其他文章)

 

目录:

1. 重叠模型的优点

2. 重叠模型的基本原理

3. 关于重叠模型的基础知识

4. 重叠模型的实现步骤

5. 多客户端情况的注意事项

 

 

一.             重叠模型的优点

1.      可以运行在支持Winsock2的所有windows平台 ,而不像完成端口只是支持NT系统。

2.      比起阻塞、select、WSAAsyncSelect以及WSAEventSelect等模型,重叠I/O(Overlapped I/O)模型使应用程序能达到更佳的系统性能。

         因为它和这4种模型不同的是,使用重叠模型的应用程序通知缓冲区收发系统直接使用数据,也就是说,如果应用程序投递了一个10KB大小的缓冲区来接收数据,且数据已经到达套接字,则该数据将直接被拷贝到投递的缓冲区。

而这4种模型种,数据到达并拷贝到单套接字接收缓冲区中,此时应用程序会被告知可以读入的容量。当应用程序调用接收函数之后,数据才从单套接字缓冲区拷贝到应用程序的缓冲区,差别就体现出来了。

3.      从《windows网络编程》中提供的试验结果中可以看到,在使用了P4 1.7G Xero处理器(CPU很强啊)以及768MB的回应服务器中,最大可以处理4万多个SOCKET连接,在处理1万2千个连接的时候CPU占用率才40% 左右 ―― 非常好的性能,已经直逼完成端口了^_^

        

 

二.             重叠模型的基本原理

      说了这么多的好处,你一定也跃跃欲试了吧,不过我们还是要先提一下重叠模型的基本原理。

      概括一点说,重叠模型是让应用程序使用重叠数据结构(WSAOVERLAPPED),一次投递一个或多个Winsock I/O请求。针对这些提交的请求,在它们完成之后,应用程序会收到通知,于是就可以通过自己另外的代码来处理这些数据了。

      需要注意的是,有两个方法可以用来管理重叠IO请求的完成情况(就是说接到重叠操作完成的通知):

1.      事件对象通知(event object notification)

2.      完成例程(completion routines) ,注意,这里并不是完成端口

而本文只是讲述如何来使用事件通知的的方法实现重叠IO模型,完成例程的方法准备放到下一篇讲 :) (内容太多了,一篇写不完啊) ,如没有特殊说明,本文的重叠模型默认就是指的基于事件通知的重叠模型。

既然是基于事件通知,就要求将windows事件对象与WSAOVERLAPPED结构关联在一起(WSAOVERLAPPED结构中专门有对应的参数),通俗一点讲,就是。。。。对了,忘了说了,既然要使用重叠结构,我们常用的send, sendto, recv, recvfrom也都要被WSASend, WSASendto, WSARecv, WSARecvFrom替换掉了, 它们的用法我后面会讲到,这里只需要注意一点,它们的参数中都有一个Overlapped参数,我们可以假设是把我们的WSARecv这样的操作操作“绑定”到这个重叠结构上,提交一个请求,其他的事情就交给重叠结构去操心,而其中重叠结构又要与windows的事件对象“绑定”在一起,这样我们调用完WSARecv以后就可以“坐享其成”,等到重叠操作完成以后,自然会有与之对应的事件来通知我们操作完成,然后我们就可以来根据重叠操作的结果取得我们想要德数据了。

      也许说了半天你还是不大明白,那就继续往后面看吧。。。。。。。-_-b,语言表达能力有限啊~~~

 

 

三.             关于重叠模型的基础知识

      下面来介绍并举例说明一下编写重叠模型的程序中将会使用到的几个关键函数。

1.      WSAOVERLAPPED结构

这个结构自然是重叠模型里的核心,它是这么定义的

typedef struct _WSAOVERLAPPED {
 
DWORD Internal;
 
 DWORD InternalHigh;
 
DWORD Offset;
 
DWORD OffsetHigh;
 
WSAEVENT hEvent;      // 唯一需要关注的参数,用来关联WSAEvent对象
       } WSAOVERLAPPED, *LPWSAOVERLAPPED;
  
我们需要把WSARecv等操作投递到一个重叠结构上,而我们又需要一个与重叠结构“绑定”在一起的事件对象来通知我们操作的完成,看到了和hEvent参数,不用我说你们也该知道如何来来把事件对象绑定到重叠结构上吧?大致如下:
  
WSAEVENT event;                   // 定义事件
  
WSAOVERLAPPED AcceptOverlapped ; // 定义重叠结构
  
event = WSACreateEvent();         // 建立一个事件对象句柄
  
ZeroMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED)); // 初始化重叠结构
  
AcceptOverlapped.hEvent = event;    // Done !!
  

  
    
  

2.      WSARecv系列函数

在重叠模型中,接收数据就要靠它了,它的参数也比recv要多,因为要用刀重叠结构嘛,它是这样定义的:

            int WSARecv(
  
                        SOCKET s,                      // 当然是投递这个操作的套接字
   
                        LPWSABUF lpBuffers,          // 接收缓冲区,与Recv函数不同
  
// 这里需要一个由WSABUF结构构成的数组
   
         DWORD dwBufferCount,        // 数组中WSABUF结构的数量
   
            LPDWORD lpNumberOfBytesRecvd,  // 如果接收操作立即完成,这里会返回函数调用
  
// 所接收到的字节数
   
          LPDWORD lpFlags,             // 说来话长了,我们这里设置为0 即可
   
          LPWSAOVERLAPPED lpOverlapped,  // “绑定”的重叠结构
   
          LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    
                               // 完成例程中将会用到的参数,我们这里设置为 NULL
   
                );
   
返回值:
   
WSA_IO_PENDING : 最常见的返回值,这是说明我们的WSARecv操作成功了,但是
  
                    I/O操作还没有完成,所以我们就需要绑定一个事件来通知我们操作何时完成
  

  
    
  
举个例子:(变量的定义顺序和上面的说明的顺序是对应的,下同)
  
SOCKET s;
  
WSABUF DataBuf;           // 定义WSABUF结构的缓冲区
  
// 初始化一下DataBuf
  
#define DATA_BUFSIZE 5096
  
char buffer[DATA_BUFSIZE];
  
ZeroMemory(buffer, DATA_BUFSIZE);
  
DataBuf.len = DATA_BUFSIZE;
  
DataBuf.buf = buffer;
  
DWORD dwBufferCount = 1, dwRecvBytes = 0, Flags = 0;
  
// 建立需要的重叠结构
  
WSAOVERLAPPED AcceptOverlapped ;// 如果要处理多个操作,这里当然需要一个
  
// WSAOVERLAPPED数组
  
WSAEVENT event;     // 如果要多个事件,这里当然也需要一个WSAEVENT数组
  
                           // 需要注意的是可能一个SOCKET同时会有一个以上的重叠请求,
  
//  也就会对应一个以上的WSAEVENT
  
Event = WSACreateEvent();
  
ZeroMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED));
  
AcceptOverlapped.hEvent = event;     // 关键的一步,把事件句柄“绑定”到重叠结构上
  
// 作了这么多工作,终于可以使用WSARecv来把我们的请求投递到重叠结构上了,呼。。。。
  
WSARecv(s, &DataBuf, dwBufferCount, &dwRecvBytes, 
  
&Flags, &AcceptOverlapped, NULL);
  
其他的函数我这里就不一一介绍了,因为我们毕竟还有MSDN这么个好帮手,而且在讲后面的完成例程和完成端口的时候我还会讲到一些 ^_^
   

  
    
  

3.      WSAWaitForMultipleEvents函数

熟悉WSAEventSelect模型的朋友对这个函数肯定不会陌生,不对,其实大家都不应该陌生,这个函数与线程中常用的WaitForMultipleObjects函数有些地方还是比较像的,因为都是在等待某个事件的触发嘛。

因为我们需要事件来通知我们重叠操作的完成,所以自然需要这个等待事件的函数与之配套。

                        DWORD WSAWaitForMultipleEvents(
  
                                  DWORD cEvents,                        // 等候事件的总数量
   
                                  const WSAEVENT* lphEvents,           // 事件数组的指针
   
                                  BOOL fWaitAll,          // 这个要多说两句:
  
                                                                  // 如果设置为 TRUE,则事件数组中所有事件被传信的时候函数才会返回
  
                                                                  // FALSE则任何一个事件被传信函数都要返回
  
                                                                  // 我们这里肯定是要设置为FALSE的
  
                                  DWORD dwTimeout,    // 超时时间,如果超时,函数会返回 WSA_WAIT_TIMEOUT
  
                               // 如果设置为0,函数会立即返回
  
                            // 如果设置为 WSA_INFINITE只有在某一个事件被传信后才会返回
  
                            // 在这里不建议设置为WSA_INFINITE,因为。。。后面再讲吧..-_-b
   
                                  BOOL fAlertable       // 在完成例程中会用到这个参数,这里我们先设置为FALSE
   
                                );
   
返回值:
   
    WSA_WAIT_TIMEOUT :最常见的返回值,我们需要做的就是继续Wait
  
    WSA_WAIT_FAILED : 出现了错误,请检查cEvents和lphEvents两个参数是否有效
  
如果事件数组中有某一个事件被传信了,函数会返回这个事件的索引值,但是这个索引值需要减去预定义值 WSA_WAIT_EVENT_0才是这个事件在事件数组中的位置。
  
具体的例子就先不在这里举了,后面还会讲到
  
注意:WSAWaitForMultipleEvents函数只能支持由WSA_MAXIMUM_WAIT_EVENTS对象定义的一个最大值,是 64,就是说WSAWaitForMultipleEvents只能等待64个事件,如果想同时等待多于64个事件,就要 创建额外的工作者线程,就不得不去管理一个线程池,这一点就不如下一篇要讲到的完成例程模型了。
  

 

4.      WSAGetOverlappedResult函数

既然我们可以通过WSAWaitForMultipleEvents函数来得到重叠操作完成的通知,那么我们自然也需要一个函数来查询一下重叠操作的结果,定义如下

            BOOL WSAGetOverlappedResult(
  
                          SOCKET s,                   // SOCKET,不用说了
  
                          LPWSAOVERLAPPED lpOverlapped,  // 这里是我们想要查询结果的那个重叠结构的指针
  
                          LPDWORD lpcbTransfer,     // 本次重叠操作的实际接收(或发送)的字节数
  
                          BOOL fWait,                // 设置为TRUE,除非重叠操作完成,否则函数不会返回
  
                                                              // 设置FALSE,而且操作仍处于挂起状态,那么函数就会返回FALSE
  
                                                              // 错误为WSA_IO_INCOMPLETE
  
                                                              // 不过因为我们是等待事件传信来通知我们操作完成,所以我们这里设
  
                // 置成什么都没有作用…..-_-b  别仍鸡蛋啊,我也想说得清楚一些…
  
                          LPDWORD lpdwFlags       // 指向DWORD的指针,负责接收结果标志
   
                        );
  
这个函数没什么难的,这里我们也不需要去关注它的返回值,直接把参数填好调用就可以了,这里就先不举例了
  
唯一需要注意一下的就是如果WSAGetOverlappedResult完成以后,第三个参数返回是 0 ,则说明通信对方已经关闭连接,我们这边的SOCKET, Event之类的也就可以关闭了。
  


Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=114883

[ 推荐本文] [ 点击此处收藏本文]   发表于 2004年09月23日 10:39 PM
href="http://blog.youkuaiyun.com/PiggyXP/Services/Pingback.aspx" rel="pingback" />

 

 
c4313848 发表于2004-09-24 9:39 AM  IP: 218.5.82.*
piggyxp兄:
总算看到传说中的文档了

 
PiggyXP(小猪) 发表于2004-09-24 1:43 PM  IP: 202.118.100.*
实在不好意思啊~~~-_-b

 
llb 发表于2004-11-24 12:07 PM  IP: 61.235.150.*
好

 
陌生人 发表于2004-12-17 11:28 PM  IP: 220.170.23.*
哈哈!看了N次才看理解啊!

留下个印!

 
mm 发表于2005-01-14 5:11 PM  IP: 202.106.132.*
重叠模型的基本原理
重叠模型适用与所有的io,但基本原理不清楚啊

 
Z 发表于2005-04-10 12:13 PM  IP: 61.51.173.*
真是不错!
不过,有别字

 
Delphityro 发表于2005-04-21 3:32 PM  IP: 211.162.70.*
改进的析构函数,可解决重复绑定出现的错误
CServerSocket::~CServerSocket()
{
TRACE("CServerSocket Îö¹¹....../n");
pServerListenThread->SuspendThread();
pOverlappedThread->SuspendThread();
closesocket(sockListen);

if(pServerListenThread != NULL)
{
DWORD dwStatus;
::GetExitCodeThread (pServerListenThread>m_hThread, &dwStatus);
if(dwStatus == STILL_ACTIVE)
{
delete pServerListenThread;
pServerListenThread = NULL;
}
}

if(pOverlappedThread != NULL)
{
DWORD dwStatus;
::GetExitCodeThread(pOverlappedThread->m_hThread, &dwStatus);
if(dwStatus == STILL_ACTIVE)
{
delete pOverlappedThread;
pOverlappedThread = NULL;
}
}
WSACleanup();
}

 
初学者 发表于2005-06-15 11:43 PM  IP: 61.186.252.*
真的写的很好,但是想问一下,你的那个例子中
SOCKET sockAcceptArray[WSA_MAXIMUM_WAIT_EVENTS]; // 与客户端通信的SOCKET
WSA_MAXIMUM_WAIT_EVENTS说最大只能为64,是不是这样的话只能同时处理64个客户端?如果要上千的客户端是不是得象你说的另开工作者线程进行处理?

 
hi_piggyxp 发表于2005-11-27 1:55 PM  IP: 219.82.146.*
期待下一篇佳作!
网络聊天室(Select异步I/O模型) 聊天室主要实现功能有: 采用UDP单播通信方式,包括服务器端和客户端。 首先启动服务器端,客户端通过用户名和密码登录服务器,服务器响应客户端登录并提示有用户登录,此时两个用户就可以进行聊天。 界面设计使用VC++ MFC,使用Select异步I/O模型。 立即下载

相关推荐

重叠IO模型

主要使用控制台程序,大致讲叙了IO模型的相关步骤以及实现C/S模型,适合初学者查看

socket 通信问题(二)socket最大连接数所受的各种限制

1、修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄)。可使用ulimit命令查看系统允许当前用户进程打开的文件数限制: [speng@as4 ~]$ ulimit -n 1024 这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去每个进程必然打开的

pingyan158的专栏 3909

基于事件通知的重叠IO模型

本代码采用C++实现,在VS2015下开发,可以直接运行,代码中有相关的注释,如发现有问题,请不吝指教,谢谢!

Socket编程模型之重叠IO(Overlapped I/O)模型

转载请注明来源:http://blog.youkuaiyun.com/caoshiying/article/details/52876090 一、原理 Winsock2的发布使得Socket I/O有了和文件I/O统一的接口。我们可以通过使用Win32文件操纵函数ReadFile和WriteFi...

cheqiane9431的博客 537

Warning-[INFL_DELTA] Too many events zero delay loop

项目场景: 运用VCS工具执行仿真的时候,遇到如下错误提示,但仿真还在继续。 Warning-[INFL_DELTA] Too many events Possible zero delay loop. Too many events in the simulation at time 0 fs. 问题描述: 为什么会有这个问题; 什么导致了这个问题; 原因分析: 1、为什么会有这个问题 由于竞争条件或编码风格不明确,可能会产生零延时回路,导致仿真挂起或仿真时间无限。 2、什么导致了这个问题 举

hh199203的博客 1万+

Mac OS X 工具技巧:一文搞定个性化命令行窗口(iTerm2 + zsh + oh-my-zsh 配置Powerline风格)

本不想写这篇文章的,因为在Linux下已经配置过很多次,想着mac应该找篇文章一次就搞定了,结果还是踩坑,看了很多文章,不是某一点没不清楚,就是截图有问题或者命令有问题,官网又难得找等等……花了3个多小时才搞定,所以,还是来总结一篇文章就能够搞定的教程。 为什么要用zsh?用了这么多年的bash,不能说bash不好,不过当我用了zsh后发现,什么叫更好用。 配置过程稍微有点繁琐,但是你看过效果...

mickjoust的技术小屋 1万+

网络程序设计——重叠I/O模型

对于网络重叠I/O操作,等待I/O操作结束的另一种方法是使用完成例程。异步的发送和接收接口函数的参数中的最后一个参数lpCompletionROUTINE就是用来指向完成例程的指针。若指定此参数,hEvent参数将被忽略,上下文信息将传送给完成例程函数。如果重叠操作立即完成,则返回0;如果重叠操作被成功初始化,并且稍后完成,则返回WSA_IO_PENDING。WinSock可以使用事件通知和完成例程两种方式来实现重叠I/O的操作。(3)两种获取传输数据数量的方法。

x20020402的博客 1199

LEF文件介绍及其生成

介绍LEF文件及其生成方法

weixin_43249158的博客 3万+

手把手教你玩转SOCKET模型之重叠I/O篇

  手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”                                                            

hzhxxx的专栏 1403

AWS 小白书 [1] 全球架构

小白应该知道的 AWS 知识

boshansolo的博客 703

天池长期赛:二手车价格预测(422方案分享)

本次比赛是一次很好的锻炼数据挖掘能力的入门赛,从EDA-数据清洗-特征工程-模型调参-模型融合,能够完整的学习到大数据的分析和挖掘,值得历练。

weixin_46685991的博客 1万+

手把手教你玩转SOCKET模型之 重叠I/O 篇

转载自小猪的手把手教你玩转SOCKET模型之 重叠I/O 篇                                                            前   言   其实我首先应该道歉,因为7月份的时候曾信誓旦旦的说要写一套关于SOCKET所有模型的入门文章以及配套代码,不过没想到后天竟然被美女所迷出去度假了,刚刚回来不久。。。。。。-_-b其实那些模型的配套代码我已

木头人专栏 1496

学Simulink--基于Simulink的无迹卡尔曼滤波(UKF)目标跟踪仿真建模示例

本文详细介绍了基于Simulink的无迹卡尔曼滤波(UKF)目标跟踪仿真建模方法。首先分析了UKF相比EKF在强非线性场景下的优势,包括无线性化误差、计算效率高和鲁棒性强等特点。接着阐述了UKF的核心原理,重点讲解了无迹变换(UT)的三个关键步骤:Sigma点生成、非线性传播和加权统计重构。文章还详细说明了二维机动目标的状态向量定义、非线性状态转移模型和雷达观测模型。 在Simulink实现部分,提供了完整的建模步骤和核心代码,包括目标运动模型、雷达传感器模型和UKF算法模块的实现。通过蛇形机动场景的仿真实

xiaoheshang_123的博客 89

手把手教你玩转SOCKET模型之重叠I/O篇 by PiggyXP【小猪】

把手教你玩转SOCKET模型之重叠I/O篇  “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”                                                                

XmagicX的专栏 2533

PCL 八叉树的使用

八叉树(Octree)是一种空间划分的数据结构,广泛应用于三维点云的处理和分析。八叉树通过将空间递归地划分为八个子区域,可以有效地组织和索引三维点数据,提升点云的查询、降采样和配准等操作的效率。

纵马踏花向自由 1658

pip install mysql出现error: subprocess - exited-with-error的解决方案

本文主要介绍了pip install mysql出现error: subprocess - exited-with-error的解决方案,希望能对使用mysql的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 5万+

手把手教你玩转SOCKET模型之重叠I/O篇(上)

手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”                                          

asdfasdfsadf 597

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

手把手教你玩转SOCKET模型之重叠I/O篇【转】

#define DATA_BUFSIZE4096// 接收缓冲区大小 SOCKET ListenSocket, // 监听套接字 AcceptSocket; // 与客户端通信的套接字 WSAOVERLAPPEDAcceptOverlapped; // 重叠结构一个 WSAE...

assdg2015的博客 202

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

转:变手把手教你玩转SOCKET模型之重叠I/O篇

手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。” ...

aolan7349的博客 220

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: 手把手教你玩转SOCKET模型之重叠I/O篇(下)
下一篇: asp简单的广告过滤处理方法
freexploit
博客等级 码龄22年 315粉丝 778原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值