VB6 WinSock控件及WinSockAPI

来源:互联网 发布:删除表 sql drop 编辑:程序博客网 时间:2024/06/09 21:01

WinSock简介
      Socket(套接字)最初是由加利福尼亚大学Berkeley(伯克利)分校为UNIX操作系统开发的网络通信接口,随着UNIX的广泛使用,Socket成为当前最流行的网络通信应用程序接口之一。20世纪90年代初,由SunMicrosystems,JSB,FTP software,Microdyne和Microsoft等几家公司共同定制了一套标准,即WindowsSocket规范,简称WinSock。

VB编写网络程序主要有两种方式:1.winsock控件 2.winsockAPI


二,WinSock控件的使用
1.WinSock控件的主要属性
a.Protocol属性

  通过Protocol属性可以设置WinSock控件连接远程计算机使用的协议。可选的协议是TCP和UDP对应的VB的常量分别是sckTCPProtocol和sckUDPProtocol,Winsock控件默认协议是TCP。注意:虽然可以在运行时设置协议,但必须在连接未建立或断开连接后。

b.SocketHandle属性
   SocketHandle返回当前socket连接的句柄,这是只读属性。

c.RemoteHostIP属性
  RemoteHostIP属性返回远程计算机的IP地址。在客户端,当使用了控件的Connect方法后,远程计算机的IP地址就赋给了RemoteHostIP属性,而在服务器端,当ConnectRequest事件后,远程计算机(客户端)的IP地址就赋给了这个属性。如果使用的是UDP协议那么当DataArrival事件后,发送UDP报文的计算机的IP才赋给了这个属性。

d.ByteReceived属性
   返回当前接收缓冲区中的字节数

e.State属性
   返回WinSock控件当前的状态

   常数                                值    描述
   sckClosed                          0     缺省值,关闭。
   SckOpen                           1     打开。
   SckListening                       2     侦听
   sckConnectionPending         3     连接挂起
   sckResolvingHost                4     识别主机。
   sckHostResolved                 5     已识别主机
   sckConnecting                    6     正在连接。
   sckConnected                    7     已连接。
   sckClosing                          8     同级人员正在关闭连接。
   sckError                             9   错误


2.WinSock主要方法
a.Bind方法

   用Bind方法可以把一个端口号固定为本控件使用,使得别的应用程序不能再使用这个端口。

b.Listen方法
   Listen方法只在使用TCP协议时有用。它将应用程序置于监听检测状态。

c.Connect方法
   当本地计算机希望和远程计算机建立连接时,就可以调用Connect方法。
   Connect方法调用的规范为:
   Connect RemoteHost,RemotePort

d.Accept方法
   当服务器接收到客户端的连接请求后,服务器有权决定是否接受客户端的请求。

e.SendData方法
   当连接建立后,要发送数据就可以调用SendData方法,该方法只有一个参数,就是要发送的数据。

f.GetData方法
   当本地计算机接收到远程计算机的数据时,数据存放在缓冲区中,要从缓冲区中取出数据,可以使用GetData方法。GetData方法调用规范如下:
   GetData data,[type,][maxLen]
   它从缓冲区中取得最长为maxLen的数据,并以type类型存放在data中,GetData取得数据后,就把相应的缓冲区清空。

g.PeekData方法
   和GetData方法类似,但PeekData在取得数据后并不把缓冲区清空。


3.Winsock控件主要事件

a.ConnectRequest事件

   当本地计算机接收到远程计算机发送的连接请求时,控件的ConnectRequest事件将会被触发。

b.SendProgress事件
   当一端的计算机正在向另一端的计算机发送数据时,SendProgress事件将被触发。SendProgress事件记录了当前状态下已发送的字节数和剩余字节数。

c.SendComplete事件
   当所有数据发送完成时,被触发。

d.DataArrival事件
   当建立连接后,接受到了新数据就会触发这个事件。注意:如果在接受到新数据前,缓冲区中非空,就不会触发这个事件。

e.Error事件
   当在工作中发生任何错误都会触发这个事件。

例子见附件

三,WinSockAPI的使用

1.WSAStartup 函数


    为了在你的应用程序当中调用任何一个Winsock API 函数,首先第一件事情你就是必须通过WSAStartup函数完成对Winsock 服务的初始化,因此需要调用WSAStartup函数。

Declare Function WSAStartup Lib "ws2_32.dll" _
    (ByVal wVersionRequired As Long, lpWSAData As WSAData) As Long

    这个函数有两个参数: wVersionRequired 和 lpWSAData。wVersionRequired 参数定义WindowsSockets 提供能使用的最高版本,它的高位字节定义的是次版本号,低位字节定义的是主版本号。下面的2个Winsock版本在VB中使用的例子:

初始化1.1版本

lngRetVal = WSAStartup(&H101, udtWinsockData)


初始化2.2版本

lngRetVal = WSAStartup(&H202, udtWinsockData)


第二个参数是WSADATA 的数据结构 ,它是接收Windows Sockets 执行时的数据。

Type WSAData
   wVersion       As Integer
   wHighVersion   As Integer
   szDescription  As String * WSADESCRIPTION_LEN
   szSystemStatus As String * WSASYS_STATUS_LEN
   iMaxSockets    As Integer
   iMaxUdpDg      As Integer
   lpVendorInfo   As Long
End Type

数据成员的描述在下表中:

Field                       描述
wVersion                Windows Sockets 版本信息。
wHighVersion           通过加载库文件得到的最高的支持Winsock 的版本,
                             它通常和wVersion值相同。
szDescription           Windows Sockets 执行时的详细描述
szSystemStatus        包含了相关的状态和配置的信息
iMaxSockets             表示同时打开的socket最大数,为0表示没有限制。
iMaxUdpDg               表示同时打开的数据报最大数,为0表示没有限制。
lpVendorInfo            厂商指定信息预留

在Winsock的1.1和2.2版本中没有lpVendorInfo的返回值。因为winsock 2支持多个传输协议,所以iMaxSockets和iMaxUdpDg只能在仅支持TCP/TP的winsock1.1中使用。为了在Winsock2中获得这些值,你可以使用WSAEnumProtocols 函数。

如果成功或者返回一个错误代码,则函数返回 0。

错误代码                            含义
WSASYSNOTREADY            指出网络没有为传输准备好。
WSAVERNOTSUPPORTED     当前的WinSock实现不支持应用程序指定的Windows Sockets规范版本
WSAEINPROGRESS              一个阻塞WinSock调用正在进行
WSAEPROCLIM                   请求的协议没有在系统中配置或没有支持它的实现存在。
WSAEFAULT                       lpWSAData 不是有效的指针



2.WSACleanup 函数

每次调用了WSAStartup函数,你都需要调用WSACleanup函数,通知系统来卸载库文件及清除已分配的资源,这个函数十分简单,没有任何参数:

Declare Function WSACleanup Lib "ws2_32.dll" () As Long


3.建立Socket函数

Declare Function socket Lib "ws2_32.dll" (ByVal af As Long, _
                  ByVal s_type As Long,
                  ByVal Protocol As Long) As Long

函数有3个参数定义建立何种socket,三个参数分别是:
Argument          Description                                           Enum Type
af                     Address family specification.                     AddressFamily
s_type              Type specification for the new socket.      SocketType
Protocol            Protocol to be used with the socket         SocketProtocol
                       that is specific to the indicated address
                       family.

AddressFamily:
    AF_UNSPEC = 0          '/* unspecified */
    AF_UNIX = 1              '/* local to host (pipes, portals) */
    AF_INET = 2              '/* internetwork: UDP, TCP, etc. */
    AF_IMPLINK = 3          '/* arpanet imp addresses */
    AF_PUP = 4                '/* pup protocols: e.g. BSP */
    AF_CHAOS = 5            '/* mit CHAOS protocols */
    AF_NS = 6                  '/* XEROX NS protocols */
    AF_IPX = AF_NS          '/* IPX protocols: IPX, SPX, etc. */
    AF_ISO = 7                 '/* ISO protocols */
    AF_OSI = AF_ISO         '/* OSI is ISO */
    AF_ECMA = 8               '/* european computer manufacturers */
    AF_DATAKIT = 9          '/* datakit protocols */
    AF_CCITT = 10             '/* CCITT protocols, X.25 etc */
    AF_SNA = 11                '/* IBM SNA */
    AF_DECnet = 12           '/* DECnet */
    AF_DLI = 13                 '/* Direct data link interface */
    AF_LAT = 14                '/* LAT */
    AF_HYLINK = 15           '/* NSC Hyperchannel */
    AF_APPLETALK = 16     '/* AppleTalk */
    AF_NETBIOS = 17        '/* NetBios-style addresses */
    AF_VOICEVIEW = 18     '/* VoiceView */
    AF_FIREFOX = 19          '/* Protocols from Firefox */
    AF_UNKNOWN1 = 20    '/* Somebody is using this! */
    AF_BAN = 21               '/* Banyan */
    AF_ATM = 22               '/* Native ATM Services */
    AF_INET6 = 23             '/* Internetwork Version 6 */
    AF_CLUSTER = 24         '/* Microsoft Wolfpack */
    AF_12844 = 25             '/* IEEE 1284.4 WG AF */
    AF_MAX = 26

Socket types:
    SOCK_STREAM = 1       ' /* stream socket */
    SOCK_DGRAM = 2         ' /* datagram socket */
    SOCK_RAW = 3            ' /* raw-protocol interface */
    SOCK_RDM = 4             ' /* reliably-delivered message */
    SOCK_SEQPACKET = 5  ' /* sequenced packet stream */

Protocols:
    IPPROTO_IP = 0                '/* dummy for IP */
    IPPROTO_ICMP = 1            '/* control message protocol */
    IPPROTO_IGMP = 2            '/* internet group management protocol */
    IPPROTO_GGP = 3             '/* gateway^2 (deprecated) */
    IPPROTO_TCP = 6             '/* tcp */
    IPPROTO_PUP = 12           '/* pup */
    IPPROTO_UDP = 17           '/* user datagram protocol */
    IPPROTO_IDP = 22            '/* xns idp */
    IPPROTO_ND = 77             '/* UNOFFICIAL net disk proto */
    IPPROTO_RAW = 255        '/* raw IP packet */
    IPPROTO_MAX = 256


该函数可以建立使用特定协议的网络套接字,例如对于UDP协议可以这样写:
s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)



4.关闭Socket函数

Declare Function closesocket Lib "ws2_32.dll" (ByVal s As Long) As Long

函数有一个参数为建立socket时的Handle




5.连接函数

Declare Function connect Lib "ws2_32.dll" (ByVal s As Long, _
                                           ByRef name As sockaddr_in, _
                                           ByVal namelen As Long) As Long

参数

s             连接的socket句柄。

name       建立连接的地址。

namelen    连接地址的长度。

返回值

成功时返回0。否则返回SOCKET_ERROR以及一个对应的错误号 Err.LastDllError。

显然在调用这个函数时我们需要知道socket句柄,将连接的电脑的端口号和主机名称(或主机IP地址)。我们知道Winsock控件的Connect方法依靠两个变量:RemoteHost和RemotePort。此方法不需要socket句柄,因其已经被封装在COM对象中。你也许认为connect函数应该也接受相同的变量设置,然而,事实并非如此。connect函数的主机地址和端口号的传送是依靠 sockaddr_in 结构。

Public Type sockaddr_in
    sin_family       As Integer
    sin_port         As Integer
    sin_addr         As Long
    sin_zero(1 To 8) As Byte
End Type




6.套接字帮定函数

Declare Function bind Lib "ws2_32.dll" (ByVal s As Long, _
                  ByRef name As sockaddr_in, _
                  ByRef namelen As Long) As Long



s是使用Socket函数创建好的套接字,name指向描述通信对象的结构体的指针,namelen是该结构的长度。该结

构体中的分量包括:
IP地址:对应name.sin_addr.s_addr

端口号:对应name.sin_port
        端口号用于表示同一台计算机上不同的进程(即应用程序),其分配方法有两种:
        第一种分配方法是,进程让系统为套接字自动分配一端口号,这只要在调用bind前将端口号指定为0即可。由系统自动分配的端口号位于1024~5000之间,而1~1023之间的任一TCP或UDP端口都是保留的,系统不允许任一进程使用保留端口,除非其有效用户ID是零(即超级用户)。
        第二种分配方法是,进程为套接字指定一特定端口。这对于需要给套接字分配一众所周知的端口的服务器是很有用的。指定范围在1024~65536之间。

地址类型:对应name.sin_family,一般都赋成AF_INET,表示是internet地址(即IP 地址)。IP地址通常使用点分表示法表示,但它事实上一个32位的长整数,这两者之间可通过inet_addr()函数转换。



7.套接字监听函数

Declare Function listen Lib "ws2_32.dll" (ByVal s As Long, ByVal backlog As Long) As Long

listen函数用来设定Socket为监听状态,这种状态表明Socket准备被连接了。注意,此函数一般在服务程序上使用,其中s是使用Socket函数创建好的套接字,backlog参数用于设定等待连接的客户端数。



8.接受连接请求

Declare Function accept Lib "ws2_32.dll" (ByVal s As Long, ByRef addr As sockaddr_in, _
                                          ByRef addrlen As Long) As Long


服务端应用程序调用此函数来接受客户端Socket连接请求,accept()函数的返回值为一新的Socket,新Socket就可用来完成服务端和客户端之间的信息传递与接收,而原来Socket仍可以接受其他可户端的连接请求。



9.接收信息

Declare Function recv Lib "ws2_32.dll" (ByVal s As Long, _
                                        ByRef buf As Any, _
                                        ByVal buflen As Long, _
                                        ByVal flags As Long) As Long


s    一个已连接的socket的识别符
buf   接受到的数据的缓冲区
len   缓冲区长度
flags 指定从哪调用的标识

第一个参数是socket的句柄-为socket函数返回值。那就是说:我们需要告诉recv函数,哪一个socket正访问函数。

第二个参数是:函数执行之后能装载一些数据的缓冲区。但它不是必须要有足够的长度接收Winsock缓冲区的所有数据,缓冲区的大小限制为8192 字节(8 Kbytes)。因此如果Winsock缓冲区的数据的大小大于recv函数的缓冲区,你必需多次调用此函数,直到获取所有的数据。

如果应用程序定义缓冲区的长度,则recv函数必须知道缓冲区可以存放多少字节。第三个参数就是为了这个目的。

最后一个参数是可选的,今天我们不使用。该参数有两个选择标志: MSG_PEEK 和 MSG_OOB,用于改变函数的行为。

MSG_PEEK 从输入数据中取数。数据拷入缓冲区,但不从输入队列中移走。函数返回当前准备接收的字节数。  
MSG_OOB 处理OOB(Out-of-band带外)数据。在网络上有两种类型的数据包,正常包和带外包。带外包可以通过检验一个TCP/IP包头的一个特定标志来决定。



10.发送信息

Declare Function send Lib "ws2_32.dll" (ByVal s As Long, _
                                        ByRef buf As Any, _
                                        ByVal buflen As Long, _
                                        ByVal flags As Long) As Long


参数参看接收信息

四,服务器与客户机交互

    目前最常用的方法是:服务程序在一个众所周知的地址(其中包括端口信息)监听对服务的请求,也就是说,服务进程一直处于休眠状态,直到一个客户对这个服务的地址提出了连接请求。这个时刻,服务程序被唤醒并对客户的请求作出适当的反应。注意,服务器与客户机之间的交互可以是面向连接的(基于流套接字),也可以是无连接的(基于数据报套接字)。


            服务器

           socket()
              |
            bind()
              |
           listen()                                       客户机
              |
              |                                           socket()
              |                     建立连接               |
           accept()   <-------------------------    connect()
              |                     请求数据               |
            recv()   <-----------------------------     send()
              |                                                |
         处理服务请求                                    |
              |                      应答数据              |
            send()    ------------------------------>   recv()
              |                                                |
           close()                                        close()




五,其他

比较:WinSock控件
               优点:使用简单,工作量小。
               缺点:功能少仅支持TCP,UDP协议,需要WinSock控件(系统默认安装不带MSWINSCK.OCX文件)
               适合于初学者
         WinSockAPI
               优点:功能强大,支持多种协议,使用灵活,WinSockAPI调用的wsock32.dll(28K)或ws2_32.dll(69K)为Windows系统自带函数库不必担心缺少文件。
               缺点:使用复杂,编程量大,需要一定基础
               适合于要求较高的网络程序


==========================================================================================================================

下面是我从网上找的一个用winsock api 写的vb6 模块

'wsksock.bas


 '   (1) I have never used WS_SELECT (select), therefore I must warn that I do

 '       not know if fd_set and timeval are properly defined.

 '   (2) Alot of the functions are declared with "buf as any", when calling these

 '       functions you may either pass strings, byte arrays or UDT's. For 32bit I

 '       I recommend Byte arrays and the use of memcopy to copy the data back out

 '   (3) The async functions (wsaAsync*) require the use of a message hook or

 '       message window control to capture messages sent by the winsock stack. This

 '       is not to be confused with a CallBack control, The only function that uses

 '       callbacks is WSASetBlockingHook()

 '   (4) Alot of "helper" functions are provided in the file for various things

 '       before attempting to figure out how to call a function, look and see if

 '       there is already a helper function for it.

 '   (5) Data types (hostent etc) have kept there 16bit definitions, even under 32bit

 '       windows due to the problem of them not working when redfined following the

 '       suggested rules.

 Option Explicit


 Public Const FD_SETSIZE = 64

 Type fd_set

     fd_count As Integer

     fd_array(FD_SETSIZE) As Integer

 End Type


 Type timeval

     tv_sec As Long

     tv_usec As Long

 End Type


 Type HostEnt

     h_name As Long

     h_aliases As Long

     h_addrtype As Integer

     h_length As Integer

     h_addr_list As Long

 End Type

 Public Const hostent_size = 16


 Type servent

     s_name As Long

     s_aliases As Long

     s_port As Integer

     s_proto As Long

 End Type

 Public Const servent_size = 14


 Type protoent

     p_name As Long

     p_aliases As Long

     p_proto As Integer

 End Type

 Public Const protoent_size = 10


 Public Const IPPROTO_TCP = 6

 Public Const IPPROTO_UDP = 17


 Public Const INADDR_NONE = &HFFFFFFFF

 Public Const INADDR_ANY = &H0


 Type sockaddr

     sin_family As Integer

     sin_port As Integer

     sin_addr As Long

     sin_zero As String * 8

 End Type

 Public Const sockaddr_size = 16

 Public saZero As sockaddr



 Public Const WSA_DESCRIPTIONLEN = 256

 Public Const WSA_DescriptionSize = WSA_DESCRIPTIONLEN + 1


 Public Const WSA_SYS_STATUS_LEN = 128

 Public Const WSA_SysStatusSize = WSA_SYS_STATUS_LEN + 1


 Type WSADataType

     wVersion As Integer

     wHighVersion As Integer

     szDescription As String * WSA_DescriptionSize

     szSystemStatus As String * WSA_SysStatusSize

     iMaxSockets As Integer

     iMaxUdpDg As Integer

     lpVendorInfo As Long

 End Type


 Public Const INVALID_SOCKET = -1

 Public Const SOCKET_ERROR = -1


 Public Const SOCK_STREAM = 1

 Public Const SOCK_DGRAM = 2


 Public Const MAXGETHOSTSTRUCT = 1024


 Public Const AF_INET = 2

 Public Const PF_INET = 2


 Type LingerType

     l_onoff As Integer

     l_linger As Integer

 End Type

 ' Windows Sockets definitions of regular Microsoft C error constants

 Global Const WSAEINTR = 10004

 Global Const WSAEBADF = 10009

 Global Const WSAEACCES = 10013

 Global Const WSAEFAULT = 10014

 Global Const WSAEINVAL = 10022

 Global Const WSAEMFILE = 10024

 ' Windows Sockets definitions of regular Berkeley error constants

 Global Const WSAEWOULDBLOCK = 10035

 Global Const WSAEINPROGRESS = 10036

 Global Const WSAEALREADY = 10037

 Global Const WSAENOTSOCK = 10038

 Global Const WSAEDESTADDRREQ = 10039

 Global Const WSAEMSGSIZE = 10040

 Global Const WSAEPROTOTYPE = 10041

 Global Const WSAENOPROTOOPT = 10042

 Global Const WSAEPROTONOSUPPORT = 10043

 Global Const WSAESOCKTNOSUPPORT = 10044

 Global Const WSAEOPNOTSUPP = 10045

 Global Const WSAEPFNOSUPPORT = 10046

 Global Const WSAEAFNOSUPPORT = 10047

 Global Const WSAEADDRINUSE = 10048

 Global Const WSAEADDRNOTAVAIL = 10049

 Global Const WSAENETDOWN = 10050

 Global Const WSAENETUNREACH = 10051

 Global Const WSAENETRESET = 10052

 Global Const WSAECONNABORTED = 10053

 Global Const WSAECONNRESET = 10054

 Global Const WSAENOBUFS = 10055

 Global Const WSAEISCONN = 10056

 Global Const WSAENOTCONN = 10057

 Global Const WSAESHUTDOWN = 10058

 Global Const WSAETOOMANYREFS = 10059

 Global Const WSAETIMEDOUT = 10060

 Global Const WSAECONNREFUSED = 10061

 Global Const WSAELOOP = 10062

 Global Const WSAENAMETOOLONG = 10063

 Global Const WSAEHOSTDOWN = 10064

 Global Const WSAEHOSTUNREACH = 10065

 Global Const WSAENOTEMPTY = 10066

 Global Const WSAEPROCLIM = 10067

 Global Const WSAEUSERS = 10068

 Global Const WSAEDQUOT = 10069

 Global Const WSAESTALE = 10070

 Global Const WSAEREMOTE = 10071

 ' Extended Windows Sockets error constant definitions

 Global Const WSASYSNOTREADY = 10091

 Global Const WSAVERNOTSUPPORTED = 10092

 Global Const WSANOTINITIALISED = 10093

 Global Const WSAHOST_NOT_FOUND = 11001

 Global Const WSATRY_AGAIN = 11002

 Global Const WSANO_RECOVERY = 11003

 Global Const WSANO_DATA = 11004

 Global Const WSANO_ADDRESS = 11004

 '---ioctl Constants

     Public Const FIONREAD = &H8004667F

     Public Const FIONBIO = &H8004667E

     Public Const FIOASYNC = &H8004667D


 #If Win16 Then

' '---Windows System functions
'
'     Public Declare Function PostMessage Lib "User" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Any) As Integer
'
'     Public Declare Sub MemCopy Lib "Kernel" Alias "hmemcpy" (Dest As Any, Src As Any, ByVal cb&)
'
'     Public Declare Function lstrlen Lib "Kernel" (ByVal lpString As Any) As Integer
'
' '---async notification constants
'
'     Public Const SOL_SOCKET = &HFFFF
'
'     Public Const SO_LINGER = &H80
'
'     Public Const FD_READ = &H1
'
'     Public Const FD_WRITE = &H2
'
'     Public Const FD_OOB = &H4
'
'     Public Const FD_ACCEPT = &H8
'
'     Public Const FD_CONNECT = &H10
'
'     Public Const FD_CLOSE = &H20
'
' '---SOCKET FUNCTIONS
'
'     Public Declare Function Accept Lib "Winsock.dll" Alias "accept" (ByVal s As Integer, addr As sockaddr, addrlen As Integer) As Integer
'
'     Public Declare Function bind Lib "Winsock.dll" (ByVal s As Integer, addr As sockaddr, ByVal namelen As Integer) As Integer
'
'     Public Declare Function closesocket Lib "Winsock.dll" (ByVal s As Integer) As Integer
'
'     Public Declare Function Connect Lib "Winsock.dll" Alias "connect" (ByVal s As Integer, addr As sockaddr, ByVal namelen As Integer) As Integer
'
'     Public Declare Function ioctlsocket Lib "Winsock.dll" (ByVal s As Integer, ByVal cmd As Long, argp As Long) As Integer
'
'     Public Declare Function getpeername Lib "Winsock.dll" (ByVal s As Integer, sName As sockaddr, namelen As Integer) As Integer
'
'     Public Declare Function getsockname Lib "Winsock.dll" (ByVal s As Integer, sName As sockaddr, namelen As Integer) As Integer
'
'     Public Declare Function getsockopt Lib "Winsock.dll" (ByVal s As Integer, ByVal level As Integer, ByVal optname As Integer, optval As Any, optlen As Integer) As Integer
'
'     Public Declare Function htonl Lib "Winsock.dll" (ByVal hostlong As Long) As Long
'
'     Public Declare Function htons Lib "Winsock.dll" (ByVal hostshort As Integer) As Integer
'
'     Public Declare Function inet_addr Lib "Winsock.dll" (ByVal cp As String) As Long
'
'     Public Declare Function inet_ntoa Lib "Winsock.dll" (ByVal inn As Long) As Long
'
'     Public Declare Function Listen Lib "Winsock.dll" Alias "listen" (ByVal s As Integer, ByVal backlog As Integer) As Integer
'
'     Public Declare Function ntohl Lib "Winsock.dll" (ByVal netlong As Long) As Long
'
'     Public Declare Function ntohs Lib "Winsock.dll" (ByVal netshort As Integer) As Integer
'
'     Public Declare Function recv Lib "Winsock.dll" (ByVal s As Integer, buf As Any, ByVal buflen As Integer, ByVal flags As Integer) As Integer
'
'     Public Declare Function recvfrom Lib "Winsock.dll" (ByVal s As Integer, buf As Any, ByVal buflen As Integer, ByVal flags As Integer, from As sockaddr, fromlen As Integer) As Integer
'
'     Public Declare Function ws_select Lib "Winsock.dll" Alias "select" (ByVal nfds As Integer, readfds As Any, writefds As Any, exceptfds As Any, timeout As timeval) As Integer
'
'     Public Declare Function Send Lib "Winsock.dll" Alias "send" (ByVal s As Integer, buf As Any, ByVal buflen As Integer, ByVal flags As Integer) As Integer
'
'     Public Declare Function sendto Lib "Winsock.dll" (ByVal s As Integer, buf As Any, ByVal buflen As Integer, ByVal flags As Integer, to_addr As sockaddr, ByVal tolen As Integer) As Integer
'
'     Public Declare Function setsockopt Lib "Winsock.dll" (ByVal s As Integer, ByVal level As Integer, ByVal optname As Integer, optval As Any, ByVal optlen As Integer) As Integer
'
'     Public Declare Function ShutDown Lib "Winsock.dll" Alias "shutdown" (ByVal s As Integer, ByVal how As Integer) As Integer
'
'     Public Declare Function socket Lib "Winsock.dll" (ByVal af As Integer, ByVal s_type As Integer, ByVal protocol As Integer) As Integer
'
' '---DATABASE FUNCTIONS
'
'     Public Declare Function gethostbyaddr Lib "Winsock.dll" (addr As Long, ByVal addr_len As Integer, ByVal addr_type As Integer) As Long
'
'     Public Declare Function gethostbyname Lib "Winsock.dll" (ByVal host_name As String) As Long
'
'     Public Declare Function gethostname Lib "Winsock.dll" (ByVal host_name As String, ByVal namelen As Integer) As Integer
'
'     Public Declare Function getservbyport Lib "Winsock.dll" (ByVal port As Integer, ByVal proto As String) As Long
'
'     Public Declare Function getservbyname Lib "Winsock.dll" (ByVal serv_name As String, ByVal proto As String) As Long
'
'     Public Declare Function getprotobynumber Lib "Winsock.dll" (ByVal proto As Integer) As Long
'
'     Public Declare Function getprotobyname Lib "Winsock.dll" (ByVal proto_name As String) As Long
'
' '---WINDOWS EXTENSIONS
'
'     Public Declare Function WSAStartup Lib "Winsock.dll" (ByVal wVR As Integer, lpWSAD As WSADataType) As Integer
'
'     Public Declare Function WSACleanup Lib "Winsock.dll" () As Integer
'
'     Public Declare Sub WSASetLastError Lib "Winsock.dll" (ByVal iError As Integer)
'
'     Public Declare Function WSAGetLastError Lib "Winsock.dll" () As Integer
'
'     Public Declare Function WSAIsBlocking Lib "Winsock.dll" () As Integer
'
'     Public Declare Function WSAUnhookBlockingHook Lib "Winsock.dll" () As Integer
'
'     Public Declare Function WSASetBlockingHook Lib "Winsock.dll" (ByVal lpBlockFunc As Long) As Long
'
'     Public Declare Function WSACancelBlockingCall Lib "Winsock.dll" () As Integer
'
'     Public Declare Function WSAAsyncGetServByName Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal serv_name As String, ByVal proto As String, buf As Any, ByVal buflen As Integer) As Integer
'
'     Public Declare Function WSAAsyncGetServByPort Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal port As Integer, ByVal proto As String, buf As Any, ByVal buflen As Integer) As Integer
'
'     Public Declare Function WSAAsyncGetProtoByName Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal proto_name As String, buf As Any, ByVal buflen As Integer) As Integer
'
'     Public Declare Function WSAAsyncGetProtoByNumber Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal number As Integer, buf As Any, ByVal buflen As Integer) As Integer
'
'     Public Declare Function WSAAsyncGetHostByName Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal host_name As String, buf As Any, ByVal buflen As Integer) As Integer
'
'     Public Declare Function WSAAsyncGetHostByAddr Lib "Winsock.dll" (ByVal hWnd As Integer, ByVal wMsg As Integer, addr As Long, ByVal addr_len As Integer, ByVal addr_type As Integer, buf As Any, ByVal buflen As Integer) As Integer
'
'     Public Declare Function WSACancelAsyncRequest Lib "Winsock.dll" (ByVal hAsyncTaskHandle As Integer) As Integer
'
'     Public Declare Function WSAAsyncSelect Lib "Winsock.dll" (ByVal s As Integer, ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal lEvent As Long) As Integer
'
'     Public Declare Function WSARecvEx Lib "Winsock.dll" (ByVal s As Integer, buf As Any, ByVal buflen As Integer, ByVal flags As Integer) As Integer

 #ElseIf Win32 Then

 '---Windows System Functions

     Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

     Public Declare Sub MemCopy Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal cb&)

     Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Any) As Long

 '---async notification constants

     Public Const SOL_SOCKET = &HFFFF&

     Public Const SO_LINGER = &H80&

     Public Const FD_READ = &H1&

     Public Const FD_WRITE = &H2&

     Public Const FD_OOB = &H4&

     Public Const FD_ACCEPT = &H8&

     Public Const FD_CONNECT = &H10&

     Public Const FD_CLOSE = &H20&

 '---SOCKET FUNCTIONS

     Public Declare Function Accept Lib "wsock32.dll" Alias "accept" (ByVal s As Long, addr As sockaddr, addrlen As Long) As Long

     Public Declare Function bind Lib "wsock32.dll" (ByVal s As Long, addr As sockaddr, ByVal namelen As Long) As Long

     Public Declare Function closesocket Lib "wsock32.dll" (ByVal s As Long) As Long

     Public Declare Function Connect Lib "wsock32.dll" Alias "connect" (ByVal s As Long, addr As sockaddr, ByVal namelen As Long) As Long

     Public Declare Function ioctlsocket Lib "wsock32.dll" (ByVal s As Long, ByVal cmd As Long, argp As Long) As Long

     Public Declare Function getpeername Lib "wsock32.dll" (ByVal s As Long, sName As sockaddr, namelen As Long) As Long

     Public Declare Function getsockname Lib "wsock32.dll" (ByVal s As Long, sName As sockaddr, namelen As Long) As Long

     Public Declare Function getsockopt Lib "wsock32.dll" (ByVal s As Long, ByVal level As Long, ByVal optname As Long, optval As Any, optlen As Long) As Long

     Public Declare Function htonl Lib "wsock32.dll" (ByVal hostlong As Long) As Long

     Public Declare Function htons Lib "wsock32.dll" (ByVal hostshort As Long) As Integer

     Public Declare Function inet_addr Lib "wsock32.dll" (ByVal cp As String) As Long

     Public Declare Function inet_ntoa Lib "wsock32.dll" (ByVal inn As Long) As Long

     Public Declare Function Listen Lib "wsock32.dll" Alias "listen" (ByVal s As Long, ByVal backlog As Long) As Long

     Public Declare Function ntohl Lib "wsock32.dll" (ByVal netlong As Long) As Long

     Public Declare Function ntohs Lib "wsock32.dll" (ByVal netshort As Long) As Integer

     Public Declare Function recv Lib "wsock32.dll" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long

     Public Declare Function recvfrom Lib "wsock32.dll" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal flags As Long, from As sockaddr, fromlen As Long) As Long

     Public Declare Function ws_select Lib "wsock32.dll" Alias "select" (ByVal nfds As Long, readfds As fd_set, writefds As fd_set, exceptfds As fd_set, timeout As timeval) As Long

     Public Declare Function Send Lib "wsock32.dll" Alias "send" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long

     Public Declare Function sendto Lib "wsock32.dll" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal flags As Long, to_addr As sockaddr, ByVal tolen As Long) As Long

     Public Declare Function setsockopt Lib "wsock32.dll" (ByVal s As Long, ByVal level As Long, ByVal optname As Long, optval As Any, ByVal optlen As Long) As Long

     Public Declare Function ShutDown Lib "wsock32.dll" Alias "shutdown" (ByVal s As Long, ByVal how As Long) As Long

     Public Declare Function socket Lib "wsock32.dll" (ByVal af As Long, ByVal s_type As Long, ByVal protocol As Long) As Long

 '---DATABASE FUNCTIONS

     Public Declare Function gethostbyaddr Lib "wsock32.dll" (addr As Long, ByVal addr_len As Long, ByVal addr_type As Long) As Long

     Public Declare Function gethostbyname Lib "wsock32.dll" (ByVal host_name As String) As Long

     Public Declare Function gethostname Lib "wsock32.dll" (ByVal host_name As String, ByVal namelen As Long) As Long

     Public Declare Function getservbyport Lib "wsock32.dll" (ByVal port As Long, ByVal proto As String) As Long

     Public Declare Function getservbyname Lib "wsock32.dll" (ByVal serv_name As String, ByVal proto As String) As Long

     Public Declare Function getprotobynumber Lib "wsock32.dll" (ByVal proto As Long) As Long

     Public Declare Function getprotobyname Lib "wsock32.dll" (ByVal proto_name As String) As Long

 '---WINDOWS EXTENSIONS

     Public Declare Function WSAStartup Lib "wsock32.dll" (ByVal wVR As Long, lpWSAD As WSADataType) As Long

     Public Declare Function WSACleanup Lib "wsock32.dll" () As Long

     Public Declare Sub WSASetLastError Lib "wsock32.dll" (ByVal iError As Long)

     Public Declare Function WSAGetLastError Lib "wsock32.dll" () As Long

     Public Declare Function WSAIsBlocking Lib "wsock32.dll" () As Long

     Public Declare Function WSAUnhookBlockingHook Lib "wsock32.dll" () As Long

     Public Declare Function WSASetBlockingHook Lib "wsock32.dll" (ByVal lpBlockFunc As Long) As Long

     Public Declare Function WSACancelBlockingCall Lib "wsock32.dll" () As Long

     Public Declare Function WSAAsyncGetServByName Lib "wsock32.dll" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal serv_name As String, ByVal proto As String, buf As Any, ByVal buflen As Long) As Long

     Public Declare Function WSAAsyncGetServByPort Lib "wsock32.dll" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal port As Long, ByVal proto As String, buf As Any, ByVal buflen As Long) As Long

     Public Declare Function WSAAsyncGetProtoByName Lib "wsock32.dll" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal proto_name As String, buf As Any, ByVal buflen As Long) As Long

     Public Declare Function WSAAsyncGetProtoByNumber Lib "wsock32.dll" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal number As Long, buf As Any, ByVal buflen As Long) As Long

     Public Declare Function WSAAsyncGetHostByName Lib "wsock32.dll" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal host_name As String, buf As Any, ByVal buflen As Long) As Long

     Public Declare Function WSAAsyncGetHostByAddr Lib "wsock32.dll" (ByVal hWnd As Long, ByVal wMsg As Long, addr As Long, ByVal addr_len As Long, ByVal addr_type As Long, buf As Any, ByVal buflen As Long) As Long

     Public Declare Function WSACancelAsyncRequest Lib "wsock32.dll" (ByVal hAsyncTaskHandle As Long) As Long

     Public Declare Function WSAAsyncSelect Lib "wsock32.dll" (ByVal s As Long, ByVal hWnd As Long, ByVal wMsg As Long, ByVal lEvent As Long) As Long

     Public Declare Function WSARecvEx Lib "wsock32.dll" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long

 #End If



 'SOME STUFF I ADDED

 Public MySocket%
 
 Public MySocketLong&

 Public SockReadBuffer$

 Public Const WSA_NoName = "Unknown"

 Public WSAStartedUp As Boolean     'Flag to keep track of whether winsock WSAStartup wascalled

 Public glngCount As Long

 Public Function WSAGetAsyncBufLen(ByVal lParam As Long) As Long

     If (lParam And &HFFFF&) > &H7FFF Then

         WSAGetAsyncBufLen = (lParam And &HFFFF&) - &H10000

     Else

         WSAGetAsyncBufLen = lParam And &HFFFF&

     End If

 End Function

 Public Function WSAGetSelectEvent(ByVal lParam As Long) As Integer

     If (lParam And &HFFFF&) > &H7FFF Then

         WSAGetSelectEvent = (lParam And &HFFFF&) - &H10000

     Else

         WSAGetSelectEvent = lParam And &HFFFF&

     End If

 End Function

 Public Function WSAGetAsyncError(ByVal lParam As Long) As Integer

     WSAGetAsyncError = (lParam And &HFFFF0000) \ &H10000

 End Function

 Public Function AddrToIP(ByVal AddrOrIP$) As String

     AddrToIP$ = GetAscIP(GetHostByNameAlias(AddrOrIP$))

 End Function

 'this function should work on 16 and 32 bit systems

 #If Win16 Then

     Function ConnectSock(ByVal host$, ByVal port%, retIpPort$, ByVal HWndToMsg%, ByVal Async%) As Integer

     Dim s%, SelectOps%, dummy%

 #ElseIf Win32 Then

     Function ConnectSock(ByVal host$, ByVal port&, retIpPort$, ByVal HWndToMsg&, ByVal Async%) As Long

     Dim s&, SelectOps&, dummy&

 #End If

     Dim sockin As sockaddr

     SockReadBuffer$ = ""

     sockin = saZero

     sockin.sin_family = AF_INET

     sockin.sin_port = htons(port)

     If sockin.sin_port = INVALID_SOCKET Then

         ConnectSock = INVALID_SOCKET

         Exit Function

     End If


     sockin.sin_addr = GetHostByNameAlias(host$)

     If sockin.sin_addr = INADDR_NONE Then

         ConnectSock = INVALID_SOCKET

         Exit Function

     End If

     retIpPort$ = GetAscIP$(sockin.sin_addr) & ":" & ntohs(sockin.sin_port)


     s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)

     If s < 0 Then

         ConnectSock = INVALID_SOCKET

         Exit Function

     End If

     If SetSockLinger(s, 1, 0) = SOCKET_ERROR Then

         If s > 0 Then

             dummy = closesocket(s)

         End If

         ConnectSock = INVALID_SOCKET

         Exit Function

     End If

     If Not Async Then

         If Not Connect(s, sockin, sockaddr_size) = 0 Then

             If s > 0 Then

                 dummy = closesocket(s)

             End If

             ConnectSock = INVALID_SOCKET

             Exit Function

         End If

         If HWndToMsg <> 0 Then

             'SelectOps = FD_READ Or FD_WRITE Or FD_CONNECT Or FD_CLOSE
             SelectOps = FD_CONNECT Or FD_CLOSE

             'If WSAAsyncSelect(s, HWndToMsg, ByVal 1025, ByVal SelectOps) Then
             If WSAAsyncSelect(s, HWndToMsg, ByVal &H200, ByVal SelectOps) Then

                 If s > 0 Then

                     dummy = closesocket(s)

                 End If

                 ConnectSock = INVALID_SOCKET

                 Exit Function

             End If

         End If

     Else

         SelectOps = FD_READ Or FD_WRITE Or FD_CONNECT Or FD_CLOSE
         SelectOps = FD_CONNECT Or FD_CLOSE

         'If WSAAsyncSelect(s, HWndToMsg, ByVal 1025, ByVal SelectOps) Then
         If WSAAsyncSelect(s, HWndToMsg, ByVal &H200, ByVal SelectOps) Then

             If s > 0 Then

                 dummy = closesocket(s)

             End If

             ConnectSock = INVALID_SOCKET

             Exit Function

         End If

         If Connect(s, sockin, sockaddr_size) <> -1 Then

             If s > 0 Then

                 dummy = closesocket(s)

             End If

             ConnectSock = INVALID_SOCKET

             Exit Function

         End If

     End If

     ConnectSock = s

 End Function

 #If Win32 Then

     Public Function SetSockLinger(ByVal SockNum&, ByVal OnOff%, ByVal LingerTime%) As Long

 #Else

     Public Function SetSockLinger(ByVal SockNum%, ByVal OnOff%, ByVal LingerTime%) As Integer

 #End If

     Dim Linger As LingerType

     Linger.l_onoff = OnOff

     Linger.l_linger = LingerTime

     If setsockopt(SockNum, SOL_SOCKET, SO_LINGER, Linger, 4) Then

         'Debug.Print "Error setting linger info: " & WSAGetLastError()

         SetSockLinger = SOCKET_ERROR

     Else

         If getsockopt(SockNum, SOL_SOCKET, SO_LINGER, Linger, 4) Then

             'Debug.Print "Error getting linger info: " & WSAGetLastError()

             SetSockLinger = SOCKET_ERROR

         Else

             'Debug.Print "Linger is on if nonzero: "; Linger.l_onoff

             'Debug.Print "Linger time if linger is on: "; Linger.l_linger

         End If

     End If

 End Function

 Sub EndWinsock()

     Dim ret&

     If WSAIsBlocking() Then

         ret = WSACancelBlockingCall()

     End If

     ret = WSACleanup()

     WSAStartedUp = False

 End Sub

 Public Function GetAscIP(ByVal inn As Long) As String

     #If Win32 Then

         Dim nStr&

     #Else

         Dim nStr%

     #End If

     Dim lpStr&

     Dim retString$

     retString = String(32, 0)

     lpStr = inet_ntoa(inn)

     If lpStr Then

         nStr = lstrlen(lpStr)

         If nStr > 32 Then nStr = 32

         MemCopy ByVal retString, ByVal lpStr, nStr

         retString = Left(retString, nStr)

         GetAscIP = retString

     Else

         GetAscIP = "255.255.255.255"

     End If

 End Function

 Public Function GetHostByAddress(ByVal addr As Long) As String

     Dim phe&, ret&

     Dim heDestHost As HostEnt

     Dim HostName$

     phe = gethostbyaddr(addr, 4, PF_INET)

     If phe Then

         MemCopy heDestHost, ByVal phe, hostent_size

         HostName = String(256, 0)

         MemCopy ByVal HostName, ByVal heDestHost.h_name, 256

         GetHostByAddress = Left(HostName, InStr(HostName, Chr(0)) - 1)

     Else

         GetHostByAddress = WSA_NoName

     End If

 End Function

 'returns IP as long, in network byte order

 Public Function GetHostByNameAlias(ByVal HostName$) As Long

     'Return IP address as a long, in network byte order

     Dim phe&

     Dim heDestHost As HostEnt

     Dim addrList&

     Dim retIP&

     retIP = inet_addr(HostName$)

     If retIP = INADDR_NONE Then

         phe = gethostbyname(HostName$)

         If phe <> 0 Then

             MemCopy heDestHost, ByVal phe, hostent_size

             MemCopy addrList, ByVal heDestHost.h_addr_list, 4

             MemCopy retIP, ByVal addrList, heDestHost.h_length

         Else

             retIP = INADDR_NONE

         End If

     End If

     GetHostByNameAlias = retIP

 End Function

 'returns your local machines name

 Public Function GetLocalHostName() As String

     Dim sName$

     sName = String(256, 0)

     If gethostname(sName, 256) Then

         sName = WSA_NoName

     Else

         If InStr(sName, Chr(0)) Then

             sName = Left(sName, InStr(sName, Chr(0)) - 1)

         End If

     End If

     GetLocalHostName = sName

 End Function

 #If Win16 Then

     Public Function GetPeerAddress(ByVal s%) As String

     Dim addrlen%

 #ElseIf Win32 Then

     Public Function GetPeerAddress(ByVal s&) As String

     Dim addrlen&

 #End If

     Dim sa As sockaddr

     addrlen = sockaddr_size

     If getpeername(s, sa, addrlen) Then

         GetPeerAddress = ""

     Else

         GetPeerAddress = SockAddressToString(sa)

     End If

 End Function

 #If Win16 Then

     Public Function GetPortFromString(ByVal PortStr$) As Integer

 #ElseIf Win32 Then

     Public Function GetPortFromString(ByVal PortStr$) As Long

 #End If

     'sometimes users provide ports outside the range of a VB

     'integer, so this function returns an integer for a string

     'just to keep an error from happening, it converts the

     'number to a negative if needed

     If Val(PortStr$) > 32767 Then

         GetPortFromString = CInt(Val(PortStr$) - &H10000)

     Else

         GetPortFromString = Val(PortStr$)

     End If

     If Err Then GetPortFromString = 0

 End Function

 #If Win16 Then

     Function GetProtocolByName(ByVal protocol$) As Integer

     Dim tmpShort%

 #ElseIf Win32 Then

     Function GetProtocolByName(ByVal protocol$) As Long

     Dim tmpShort&

 #End If

     Dim ppe&

     Dim peDestProt As protoent

     ppe = getprotobyname(protocol)

     If ppe Then

         MemCopy peDestProt, ByVal ppe, protoent_size

         GetProtocolByName = peDestProt.p_proto

     Else

         tmpShort = Val(protocol)

         If tmpShort Then

             GetProtocolByName = htons(tmpShort)

         Else

             GetProtocolByName = SOCKET_ERROR

         End If

     End If

 End Function

 #If Win16 Then

     Function GetServiceByName(ByVal service$, ByVal protocol$) As Integer

     Dim serv%

 #ElseIf Win32 Then

     Function GetServiceByName(ByVal service$, ByVal protocol$) As Long

     Dim serv&

 #End If

     Dim pse&

     Dim seDestServ As servent

     pse = getservbyname(service, protocol)

     If pse Then

         MemCopy seDestServ, ByVal pse, servent_size

         GetServiceByName = seDestServ.s_port

     Else

         serv = Val(service)

         If serv Then

             GetServiceByName = htons(serv)

         Else

             GetServiceByName = INVALID_SOCKET

         End If

     End If

 End Function

 'this function DOES work on 16 and 32 bit systems

 #If Win16 Then

     Function GetSockAddress(ByVal s%) As String

     Dim addrlen%

     Dim ret%

 #ElseIf Win32 Then

     Function GetSockAddress(ByVal s&) As String

     Dim addrlen&

     Dim ret&

 #End If

     Dim sa As sockaddr

     Dim szRet$

     szRet = String(32, 0)

     addrlen = sockaddr_size

     If getsockname(s, sa, addrlen) Then

         GetSockAddress = ""

     Else

         GetSockAddress = SockAddressToString(sa)

     End If

 End Function

 'this function should work on 16 and 32 bit systems

 Function GetWSAErrorString(ByVal errnum&) As String

     On Error Resume Next

     Select Case errnum

         Case 10004: GetWSAErrorString = "Interrupted system call."

         Case 10009: GetWSAErrorString = "Bad file number."

         Case 10013: GetWSAErrorString = "Permission Denied."

         Case 10014: GetWSAErrorString = "Bad Address."

         Case 10022: GetWSAErrorString = "Invalid Argument."

         Case 10024: GetWSAErrorString = "Too many open files."

         Case 10035: GetWSAErrorString = "Operation would block."

         Case 10036: GetWSAErrorString = "Operation now in progress."

         Case 10037: GetWSAErrorString = "Operation already in progress."

         Case 10038: GetWSAErrorString = "Socket operation on nonsocket."

         Case 10039: GetWSAErrorString = "Destination address required."

         Case 10040: GetWSAErrorString = "Message too long."

         Case 10041: GetWSAErrorString = "Protocol wrong type for socket."

         Case 10042: GetWSAErrorString = "Protocol not available."

         Case 10043: GetWSAErrorString = "Protocol not supported."

         Case 10044: GetWSAErrorString = "Socket type not supported."

         Case 10045: GetWSAErrorString = "Operation not supported on socket."

         Case 10046: GetWSAErrorString = "Protocol family not supported."

         Case 10047: GetWSAErrorString = "Address family not supported by protocol family."

         Case 10048: GetWSAErrorString = "Address already in use."

         Case 10049: GetWSAErrorString = "Can't assign requested address."

         Case 10050: GetWSAErrorString = "Network is down."

         Case 10051: GetWSAErrorString = "Network is unreachable."

         Case 10052: GetWSAErrorString = "Network dropped connection."

         Case 10053: GetWSAErrorString = "Software caused connection abort."

         Case 10054: GetWSAErrorString = "Connection reset by peer."

         Case 10055: GetWSAErrorString = "No buffer space available."

         Case 10056: GetWSAErrorString = "Socket is already connected."

         Case 10057: GetWSAErrorString = "Socket is not connected."

         Case 10058: GetWSAErrorString = "Can't send after socket shutdown."

         Case 10059: GetWSAErrorString = "Too many references: can't splice."

         Case 10060: GetWSAErrorString = "Connection timed out."

         Case 10061: GetWSAErrorString = "Connection refused."

         Case 10062: GetWSAErrorString = "Too many levels of symbolic links."

         Case 10063: GetWSAErrorString = "File name too long."

         Case 10064: GetWSAErrorString = "Host is down."

         Case 10065: GetWSAErrorString = "No route to host."

         Case 10066: GetWSAErrorString = "Directory not empty."

         Case 10067: GetWSAErrorString = "Too many processes."

         Case 10068: GetWSAErrorString = "Too many users."

         Case 10069: GetWSAErrorString = "Disk quota exceeded."

         Case 10070: GetWSAErrorString = "Stale NFS file handle."

         Case 10071: GetWSAErrorString = "Too many levels of remote in path."

         Case 10091: GetWSAErrorString = "Network subsystem is unusable."

         Case 10092: GetWSAErrorString = "Winsock DLL cannot support this application."

         Case 10093: GetWSAErrorString = "Winsock not initialized."

         Case 10101: GetWSAErrorString = "Disconnect."

         Case 11001: GetWSAErrorString = "Host not found."

         Case 11002: GetWSAErrorString = "Nonauthoritative host not found."

         Case 11003: GetWSAErrorString = "Nonrecoverable error."

         Case 11004: GetWSAErrorString = "Valid name, no data record of requested type."

         Case Else:  GetWSAErrorString = "Unexpert Error!"

     End Select

 End Function

 'this function DOES work on 16 and 32 bit systems

 Function IpToAddr(ByVal AddrOrIP$) As String

     On Error Resume Next

     IpToAddr = GetHostByAddress(GetHostByNameAlias(AddrOrIP$))

     If Err Then IpToAddr = WSA_NoName

 End Function

 'this function DOES work on 16 and 32 bit systems

 Function IrcGetAscIp(ByVal IPL$) As String

     'this function is IRC specific, it expects a long ip stored in Network byte order, in a string

     'the kind that would be parsed out of a DCC command string

     On Error GoTo IrcGetAscIPError:

     Dim lpStr&

 #If Win16 Then

     Dim nStr%

 #ElseIf Win32 Then

     Dim nStr&

 #End If

     Dim retString$

     Dim inn&

     If Val(IPL) > 2147483647 Then

         inn = Val(IPL) - 4294967296#

     Else

         inn = Val(IPL)

     End If

     inn = ntohl(inn)

     retString = String(32, 0)

     lpStr = inet_ntoa(inn)

     If lpStr = 0 Then

         IrcGetAscIp = "0.0.0.0"

         Exit Function

     End If

     nStr = lstrlen(lpStr)

     If nStr > 32 Then nStr = 32

     MemCopy ByVal retString, ByVal lpStr, nStr

     retString = Left(retString, nStr)

     IrcGetAscIp = retString

     Exit Function

IrcGetAscIPError:

     IrcGetAscIp = "0.0.0.0"

     Exit Function

     Resume

 End Function

 'this function DOES work on 16 and 32 bit systems

 Function IrcGetLongIp(ByVal AscIp$) As String

     'this function converts an ascii ip string into a long ip in network byte order

     'and stick it in a string suitable for use in a DCC command.

     On Error GoTo IrcGetLongIpError:

     Dim inn&

     inn = inet_addr(AscIp)

     inn = htonl(inn)

     If inn < 0 Then

         IrcGetLongIp = CVar(inn + 4294967296#)

         Exit Function

     Else

         IrcGetLongIp = CVar(inn)

         Exit Function

     End If

     Exit Function

IrcGetLongIpError:

     IrcGetLongIp = "0"

     Exit Function

     Resume

 End Function
 
 'this function should work on 16 and 32 bit systems

 #If Win16 Then

 Public Function ListenForConnect(ByVal port%, ByVal HWndToMsg%) As Integer

     Dim s%, dummy%

     Dim SelectOps%

 #ElseIf Win32 Then

 Public Function ListenForConnect(ByVal port&, ByVal HWndToMsg&) As Long

     Dim s&, dummy&

     Dim SelectOps&

 #End If

     Dim sockin As sockaddr

     sockin = saZero     'zero out the structure

     sockin.sin_family = AF_INET

     sockin.sin_port = htons(port)

     If sockin.sin_port = INVALID_SOCKET Then

         ListenForConnect = INVALID_SOCKET

         Exit Function

     End If

     sockin.sin_addr = htonl(INADDR_ANY)

     If sockin.sin_addr = INADDR_NONE Then

         ListenForConnect = INVALID_SOCKET

         Exit Function

     End If

     s = socket(PF_INET, SOCK_STREAM, 0)

     If s < 0 Then

         ListenForConnect = INVALID_SOCKET

         Exit Function

     End If

     If bind(s, sockin, sockaddr_size) Then

         If s > 0 Then

             dummy = closesocket(s)

         End If

         ListenForConnect = INVALID_SOCKET

         Exit Function

     End If

     SelectOps = FD_READ Or FD_WRITE Or FD_CLOSE Or FD_ACCEPT
     SelectOps = FD_CLOSE Or FD_ACCEPT

     'If WSAAsyncSelect(s, HWndToMsg, ByVal 1025, ByVal SelectOps) Then
     If WSAAsyncSelect(s, HWndToMsg, ByVal &H200, ByVal SelectOps) Then

         If s > 0 Then

             dummy = closesocket(s)

         End If

         ListenForConnect = SOCKET_ERROR

         Exit Function

     End If

    

     If Listen(s, 1) Then

         If s > 0 Then

             dummy = closesocket(s)

         End If

         ListenForConnect = INVALID_SOCKET

         Exit Function

     End If

     ListenForConnect = s

 End Function

 'this function should work on 16 and 32 bit systems

 #If Win16 Then

 Public Function SendData(ByVal s%, vMessage As Variant) As Integer

 #ElseIf Win32 Then

 Public Function SendData(ByVal s&, vMessage As Variant) As Long

 #End If

     Dim TheMsg() As Byte, sTemp$

     Select Case VarType(vMessage)

         Case 8209   'byte array

             sTemp = vMessage
        
         Case 8      'string, if we recieve a string, its assumed we are linemode

             sTemp = StrConv(vMessage, vbFromUnicode)
             'sTemp = vMessage ', vbFromUnicode)
         Case Else

             sTemp = CStr(vMessage)

     End Select

     TheMsg = sTemp

     If UBound(TheMsg) > -1 Then

         SendData = Send(s, TheMsg(0), UBound(TheMsg) + 1, 0)

     End If

 End Function

 Public Function SockAddressToString(sa As sockaddr) As String

     SockAddressToString = GetAscIP(sa.sin_addr) & ":" & ntohs(sa.sin_port)

 End Function

 Public Function StartWinsock(sDescription As String) As Boolean

     Dim StartupData As WSADataType

     If Not WSAStartedUp Then

         If Not WSAStartup(&H101, StartupData) Then

             WSAStartedUp = True

             Debug.Print "wVersion="; StartupData.wVersion, "wHighVersion="; StartupData.wHighVersion
 
             Debug.Print "If wVersion == 257 then everything is kewl"
 
             Debug.Print "szDescription="; StartupData.szDescription
 
             Debug.Print "szSystemStatus="; StartupData.szSystemStatus
 
             Debug.Print "iMaxSockets="; StartupData.iMaxSockets, "iMaxUdpDg="; StartupData.iMaxUdpDg

             sDescription = StartupData.szDescription

         Else

             WSAStartedUp = False

         End If

     End If
    
     #If Win16 Then
         Debug.Print "Win16"
     #ElseIf Win32 Then
         Debug.Print "Win32"
     #End If

     StartWinsock = WSAStartedUp

 End Function
 
 Public Function WSAMakeSelectReply(TheEvent%, TheError%) As Long

     WSAMakeSelectReply = (TheError * &H10000) + (TheEvent And &HFFFF&)

 End Function



其中“#If Win16 Then” 条件下的代码可以注释掉不用。

使用方法如下:


Dim strDesc As String
Dim strIpPort As String

Private Sub cmdConnect_Click()
    
    WskSock.StartWinsock (strDesc)
    WskSock.MySocketLong = WskSock.ConnectSock("172.17.71.107", 8000, strIpPort, 0, 0)
    Text2.Text = strDesc & "---" & strIpPort
End Sub


Private Sub cmdSend_Click()

    rc = Send(sll, ByVal "Hello World!", Len("Hello World!"), 0)
    
End Sub


Private Sub cmdClose_Click()
    WskSock.closesocket WskSock.MySocketLong
    WskSock.EndWinsock
End Sub


如果上面的模块觉得不好用可以下面的链接下载高手封装的模块

CSocketMaster:  http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=54681&lngWId=1 纯api编写,用法跟winsock无异。