How WinSock works

本文详细阐述了WinSock的工作原理,包括其作为灵活多态Berkeley sockets API的实现方式,以及如何在用户模式和内核模式下运行,并通过特定的MS调用实现NT的重叠IO。文章还解释了WinSock API调用如何处理Berkeley和WSAxxxc调用,以及如何自定义ReadFile和WriteFile等操作。

 

How WinSock works (from osronline)

WinSock is the flexible polymorphic implementation of Berkeley sockets API,
which is implemented in both user and kernel mode, and which has the addition
of MS-specific calls which implement the NT's overlapped IO on sockets.

WinSock APIs are in is wsock32.dll/ws2_32.dll, which in turn looks in the
registry and load the proper provider DLL. This allows you to implement your
own address families _fully in user mode_, or as a mix of your own proprietary
user+kernel modules with your own interface between user and kernel part.

Actually, WinSock API calls do the following - "get the provider's function
table by socket handle value" and then "call the provider's function".

This is OK for all Berkeley and WSAxxx calls.

But note that ReadFile and WriteFile are always supported on a socket handle -
in NT, SOCKET is just a kernel file handle. If we are speaking about send() -
then send() is in WinSock, and WinSock is free to implement any semantics on
it. But, if we are speaking about ReadFile, then sorry, this API is not in
WinSock and the standard NT API which knows nothing on sockets, then only way
of customizing ReadFile is to customize its kernel part.

To support ReadFile on user-mode WinSock provider DLLs (user-mode address
families), there is an auxiliary driver called ws2ifsl.sys. To employ this
driver, the provider DLL must call the WinSock's provider interface function
"create IFS handle" or such. This call will create a pair of file handles on
ws2ifsl, will create the necessary thread pool for inverted calls, will
associate the slave handle with the provider's function table and will return
the master handle to the provider DLL. Then the provider DLL returns this
handle from its WSPSocket.

When the app calls Read/WriteFile on this handle, the calls go directly (no
WinSock!) to ws2ifsl.sys in kernel. This module transfers the call to the slave
end of its conceptual "pipe", and the thread pool in ws2_32.dll will consume
the call (yes, inverted call) and execute it by calling some WSPXxx in the
provider DLL.

But this is not the typical scenario of socket address family implementation.
The typical scenario is that the address family package has the kernel part,
which automatically guarantees that the socket handle will be the file handle
on this kernel part. Such packages use "register IFS handle" instead of "create
IFS handle", their WSPSocket path first does CreateFile on their kernel part,
and then "register IFS handle". The second step is needed for functions like
send() to be dispatched to this provider's WSPSend. Read/WriteFile are
automatically delivered to the kernel part.

Now note that many address families have lots of common in them - buffering,
listen backlog, lingering closes to say a few. So, the common layer which
implements all of this was created, and also this same layer serves as default
kernel-mode WinSock provider. This module is called AFD.SYS.

So, if the address family implementor needs a kernel part, then the existing
AFD.SYS can be reused as a framework. To reuse it, one must program to the
lower-edge interface of AFD, which is called TDI.

TDI is much more low-level then socket calls. For instance, the TDI transports
usually (surely this is true on TCPIP) have no buffering at all. So, TDI_SEND
operation is kept pending _till all ACKs will arrive_. The reason is that,
while the ACKs have not arrive yet, there is a possibility that there will be a
need for retransmit. Now note that the transport does no buffering, no data
copies, so, if it would complete the original send request - it will have the
data for the retransmit no more. So, TDI_SEND on unbuffered (the usual way,
TCPIP's too) transport pends till all ACKs will arrive, and retransmits are
handled off the same send request's buffer.

On receive and accept, TDI uses the 2phase interaction - first is
ClientEventReceive/Connect about incoming connection offer or incoming data
portion, second is the TDI_ACCEPT or TDI_RECEIVE completion routine. On accept,
this allows (and requires) the client to create the new TDI endpoint (accept's
target) itself, and then associate it with this particular incoming connection
offer. This allows to implement listen backlog above the transport, and also
allows to extend this "accept to specified pre-created socket" feature to user
mode as overlapped AcceptEx API.

On receive, this allows the client to own the memory buffers for the received
data, no need to allocate them in transport. Also this allows to first receive
the header, access it, determine the data portion size which will follow (like
SMB WRITE transaction), then get this data in nonblocking way with only 1 copy.

Also there are other operation modes in TDI like chained receive etc.

If the provider of some address family (like IrDA) is implemented as
kernel-mode TDI transport - then it automatically reused AFD.SYS layer, which
a) exposes it to user-mode WinSock b) implements buffers/listen
backlog/lingering close.

The second part of this "default WinSock provider" is the user mode provider
DLL, called MSAFD.DLL, which is nearly totally consists of DeviceIoControl
calls to AFD.SYS.

Surely default WinSock provider cannot support protocol-dependent stuff like
socket options other then SOL_SOCKET. To implement them, MSAFD requires
address-family-specific helper DLL, which is - for TCPIP - given as the
WSHSMPLE sample in the DDK.

The differences with Linux:

- Berkeley calls are syscalls in Linux, but are user-mode wrappers around
DeviceIoControl in Windows, MSAFD.DLL is a wrapper (and, if you use only TCPIP,
all WinSock userland is a wrapper), AFD.SYS is the kernel module where they
arrive. Also it was so in SunOS 5.2/Solaris 2.x with their /dev/nit - so, AFD
is the same as "nit" kernel module in SunOS, which is in turn the same as
"sockfs" in Linux.

- in Linux and FreeBSD, kernel-mode clients talking directly to TCP without
sockets - with their own listen backlog and buffering - are not permitted. They
are permitted in Windows. Instead, socket API is absent in kmode in Windows at
all, though implementable as wrapper around TDI.

You cannot use _select()_ in Windows on anything but sockets, since select() in
Windows is not a generic kernel notion, but a socket-only notion, possibly
built around WSAEventSelect. You also cannot use select with 3 NULLs as sleep.

But you can use Read/WriteFile on a socket.

 

 

config.status: creating include/libxml/Makefile config.status: creating doc/Makefile config.status: creating doc/examples/Makefile config.status: creating doc/devhelp/Makefile config.status: creating example/Makefile config.status: creating fuzz/Makefile config.status: creating python/Makefile config.status: creating python/tests/Makefile config.status: creating xstc/Makefile config.status: creating include/libxml/xmlversion.h config.status: creating libxml-2.0.pc config.status: creating libxml-2.0-uninstalled.pc config.status: creating libxml2-config.cmake config.status: creating python/setup.py yes yes checking for windows.h... config.status: creating xml2-config checking for inttypes.h... yes config.status: creating config.h checking for memory.h... yes config.status: executing depfiles commands checking whether the C compiler works... checking for unistd.h... yes checking for stdint.h... yes checking for C compiler default output file name... a.out checking for suffix of executables... config.status: executing libtool commands Done configuring install xml-2.9.12 HEADFILES [100%] Built target prebuild_libxml2 no checking whether build target is a native Windows one... no yes checking for int64_t... checking whether build target supports WIN32 file API... no checking whether to support http... yes checking whether to support ftp... yes checking whether to support file... yes checking whether to support ldap... yes checking whether to support ldaps... yes checking whether to support rtsp... yes checking whether to support proxies... yes checking whether to support dict... yes checking whether to support telnet... yes checking whether to support tftp... yes checking whether to support pop3... yes checking whether to support imap... yes checking whether to support smb... yes checking whether to support smtp... yes checking whether to support gopher... yes checking whether to provide built-in manual... yes checking whether to enable generation of C code... yes checking whether to use libgcc... no checking if X/Open network library is required... no checking *printf() support for %lld... checking *printf() support for %qd... checking size of bool... checking whether we are cross compiling... yes checking for strings.h... yes yes checking minix/config.h usability... checking for unistd.h... yes no checking for gethostbyname... checking for inttypes.h... yes configure libnetfilter_conntrack-1.0.4 ... checking for suffix of object files... yes checking for windows.h... (cached) no checking for winsock.h... (cached) no checking for winsock2.h... (cached) no checking for connect in libraries... yes checking whether __UCLIBC__ is declared... checking build system type... x86_64-unknown-linux-gnu checking host system type... arm-hsan-linux-gnu checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... no checking minix/config.h presence... yes checking for u_int64_t... o checking whether we are using the GNU C compiler... 0 checking if true is defined... yes yes checking whether /usr/bin/ccache /home/his/jxl/code/HiSmartHub1_2_T05linux/sample/tmp/tiangong0_cmcc_hgu_release/tools/cross_toolchain/arm-mix510-linux/arm-mix510-linux/bin/arm-mix510-linux-gcc -DCONFIG_HSAN accepts -g... no checking for minix/config.h... no checking whether it is safe to define __EXTENSIONS__... checking for stdint.h... yes checking whether time.h and sys/time.h may both be included... yes checking for arm-hsan-linux-strip... /home/his/jxl/code/HiSmartHub1_2_T05linux/sample/tmp/tiangong0_cmcc_hgu_release/tools/cross_toolchain/arm-mix510-linux/arm-mix510-linux/bin/arm-mix510-linux-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking how to create a pax tar archive... gnutar checking for style of include used by make... GNU checking for arm-hsan-linux-gcc... /usr/bin/ccache /home/his/jxl/code/HiSmartHub1_2_T05linux/sample/tmp/tiangong0_cmcc_hgu_release/tools/cross_toolchain/arm-mix510-linux/arm-mix510-linux/bin/arm-mix510-linux-gcc -DCONFIG_HSAN no checking for crypt... yes checking whether byte ordering is bigendian... yes checking for /usr/bin/ccache /home/his/jxl/code/HiSmartHub1_2_T05linux/sample/tmp/tiangong0_cmcc_hgu_release/tools/cross_toolchain/arm-mix510-linux/arm-mix510-linux/bin/arm-mix510-linux-gcc -DCONFIG_HSAN option to accept ISO C89... yes checking for unistd.h... yes checking for sys/types.h... (cached) yes yes checking for crypt in -lcrypt... checking sys/time.h usability... yes checking whether byte ordering is bigendian... none needed checking for style of include used by make... checking whether the C compiler works... GNU checking dependency style of /usr/bin/ccache /home/his/jxl/code/HiSmartHub1_2_T05linux/sample/tmp/tiangong0_cmcc_hgu_release/tools/cross_toolchain/arm-mix510-linux/arm-mix510-linux/bin/arm-mix510-linux-gcc -DCONFIG_HSAN... yes checking for special C compiler options needed for large files... no checking for _FILE_OFFSET_BITS value needed for large files... yes configure: Disabling zlib configure: Disabling PAM configure: Using openpty if available checking for library containing openpty... yes checking for C compiler default output file name... a.out checking for suffix of executables... no 可以依靠这一句:checking whether to support telnet… yes来打开telnet吗?如果不能,这一句是什么意思
07-31
数据集介绍:垃圾分类检测数据集 一、基础信息 数据集名称:垃圾分类检测数据集 图片数量: 训练集:2,817张图片 验证集:621张图片 测试集:317张图片 总计:3,755张图片 分类类别: - 金属:常见的金属垃圾材料。 - 纸板:纸板类垃圾,如包装盒等。 - 塑料:塑料类垃圾,如瓶子、容器等。 标注格式: YOLO格式,包含边界框和类别标签,适用于目标检测任务。 数据格式:图片来源于实际场景,格式为常见图像格式(如JPEG/PNG)。 二、适用场景 智能垃圾回收系统开发: 数据集支持目标检测任务,帮助构建能够自动识别和分类垃圾材料的AI模型,用于自动化废物分类和回收系统。 环境监测与废物管理: 集成至监控系统或机器人中,实时检测垃圾并分类,提升废物处理效率和环保水平。 学术研究与教育: 支持计算机视觉与环保领域的交叉研究,用于教学、实验和论文发表。 三、数据集优势 类别覆盖全面: 包含三种常见垃圾材料类别,覆盖日常生活中主要的可回收物类型,具有实际应用价值。 标注精准可靠: 采用YOLO标注格式,边界框定位精确,类别标签准确,便于模型直接训练和使用。 数据量适中合理: 训练集、验证集和测试集分布均衡,提供足够样本用于模型学习和评估。 任务适配性强: 标注兼容主流深度学习框架(如YOLO等),可直接用于目标检测任务,支持垃圾检测相关应用。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值