home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 5_2007-2008.ISO / data / Zips / HTTP_Class2082709102007.psc / CSocket.cls < prev   
Text File  |  2007-09-07  |  15KB  |  428 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "CSocket"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = False
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. '********************************************************************************
  15. 'CSocket class
  16. 'Copyright ⌐ 2002 by Oleg Gdalevich
  17. 'Visual Basic Internet Programming website (http://www.vbip.com)
  18. '********************************************************************************
  19. 'To use this class module you need:
  20. '   MSocketSupport code module
  21. '********************************************************************************
  22. 'Version: 1.0.12     Modified: 17-OCT-2002
  23. '********************************************************************************
  24. 'To get latest version of this code please visit the following web page:
  25. 'http://www.vbip.com/winsock-api/csocket-class/csocket-class-01.asp
  26. '********************************************************************************
  27. Option Explicit
  28. '
  29. 'Added: 23-AUG-2002
  30. Private 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
  31. '
  32. 'The CSocket protocol's constants as for
  33. 'the MS Winsock Control interface
  34. Public Enum ProtocolConstants
  35.     sckTCPProtocol = 0
  36.     sckUDPProtocol = 1
  37. End Enum
  38. '
  39. 'The CSocket error's constants as for
  40. 'the MS Winsock Control interface
  41. Public Enum ErrorConstants
  42.     sckAddressInUse = 10048
  43.     sckAddressNotAvailable = 10049
  44.     sckAlreadyComplete = 10037
  45.     sckAlreadyConnected = 10056
  46.     sckBadState = 40006
  47.     sckConnectAborted = 10053
  48.     sckConnectionRefused = 10061
  49.     sckConnectionReset = 10054
  50.     sckGetNotSupported = 394
  51.     sckHostNotFound = 11001
  52.     sckHostNotFoundTryAgain = 11002
  53.     sckInProgress = 10036
  54.     sckInvalidArg = 40014
  55.     sckInvalidArgument = 10014
  56.     sckInvalidOp = 40020
  57.     sckInvalidPropertyValue = 380
  58.     sckMsgTooBig = 10040
  59.     sckNetReset = 10052
  60.     sckNetworkSubsystemFailed = 10050
  61.     sckNetworkUnreachable = 10051
  62.     sckNoBufferSpace = 10055
  63.     sckNoData = 11004
  64.     sckNonRecoverableError = 11003
  65.     sckNotConnected = 10057
  66.     sckNotInitialized = 10093
  67.     sckNotSocket = 10038
  68.     sckOpCanceled = 10004
  69.     sckOutOfMemory = 7
  70.     sckOutOfRange = 40021
  71.     sckPortNotSupported = 10043
  72.     sckSetNotSupported = 383
  73.     sckSocketShutdown = 10058
  74.     sckSuccess = 40017
  75.     sckTimedout = 10060
  76.     sckUnsupported = 40018
  77.     sckWouldBlock = 10035
  78.     sckWrongProtocol = 40026
  79. End Enum
  80. '
  81. 'The CSocket state's constants as for
  82. 'the MS Winsock Control interface
  83. Public Enum StateConstants
  84.     sckClosed = 0
  85.     sckOpen
  86.     sckListening
  87.     sckConnectionPending
  88.     sckResolvingHost
  89.     sckHostResolved
  90.     sckConnecting
  91.     sckConnected
  92.     sckClosing
  93.     sckError
  94. End Enum
  95. '
  96. 'In order to resolve a host name the MSocketSupport.ResolveHost
  97. 'function can be called from the Connect and SendData methods
  98. 'of this class. The callback acceptor for that routine is the
  99. 'PostGetHostEvent procedure. This procedure determines what to
  100. 'do next with the received host's address checking a value of
  101. 'the m_varInternalState variable.
  102. Private Enum InternalStateConstants
  103.     istConnecting
  104.     istSendingDatagram
  105. End Enum
  106. '
  107. Private m_varInternalState As InternalStateConstants
  108. '
  109. 'Local (module level) variables to hold values of the
  110. 'properties of this (CSocket) class.
  111. Private mvarProtocol        As ProtocolConstants
  112. Private mvarState           As StateConstants
  113. Private m_lngBytesReceived  As Long
  114. Private m_strLocalHostName  As String
  115. Private m_strLocalIP        As String
  116. Private m_lngLocalPort      As Long
  117. Private m_strRemoteHost     As String
  118. Private m_strRemoteHostIP   As String
  119. Private m_lngRemotePort     As Long
  120. Private m_lngSocketHandle   As Long
  121. '
  122. 'Resolving host names is performed in an asynchronous mode,
  123. 'the m_lngRequestID variable just holds the value returned
  124. 'by the ResolveHost function from the MSocketSupport module.
  125. Private m_lngRequestID      As Long
  126. '
  127. 'Internal (for this class) buffers. They are the VB Strings.
  128. 'Don't trust that guy who told that the VB String data type
  129. 'cannot properly deal with binary data. Actually, it can, and
  130. 'moreover you have a lot of means to deal with that data -
  131. 'the VB string functions (such as Left, Mid, InStr and so on).
  132. 'If you need to get a byte array from a string, just call the
  133. 'StrConv function:
  134. '
  135. 'byteArray() = StrConv(strBuffer, vbFromUnicode)
  136. '
  137. Private m_strSendBuffer     As String 'The internal buffer for outgoing data
  138. Private m_strRecvBuffer     As String 'The internal buffer for incoming data
  139. '
  140. 'Lenght of the Winsock buffers. By default = 8192 bytes for TCP sockets.
  141. 'These values are initialized in the SocketExists function.
  142. 'Now, I really don't know why I was in need to get these values.
  143. Private m_lngSendBufferLen  As Long
  144. Private m_lngRecvBufferLen  As Long
  145. '
  146. 'Maximum size of a datagram that can be sent through
  147. 'a message-oriented (UDP) socket. This value is returned
  148. 'by the InitWinsock function from the MSocketSupport module.
  149. Private m_lngMaxMsgSize     As Long
  150. '
  151. 'This flag variable indicates that the socket is bound to
  152. 'some local socket address
  153. Private m_blnSocketIsBound  As Boolean  'Added: 10-MAR-2002
  154. '
  155. Private m_blnSendFlag As Boolean        'Added: 12-SEP-2002
  156. '
  157. 'This flag variable indicates that the SO_BROADCAST option
  158. 'is set on the socket
  159. Private m_blnBroadcast      As Boolean  'Added: 09-JULY-2002
  160. '
  161. 'These are those MS Winsock's events.
  162. 'Pay attention that the "On" prefix is added.
  163. Public Event OnClose()
  164. Public Event OnConnect()
  165. Public Event OnConnectionRequest(ByVal requestID As Long)
  166. Public Event OnDataArrival(ByVal bytesTotal As Long)
  167. Public Event OnError(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
  168. Public Event OnSendComplete()
  169. Public Event OnSendProgress(ByVal bytesSent As Long, ByVal bytesRemaining As Long)
  170.  
  171. Public Sub SendData(varData As Variant)
  172.     '
  173.     'data to send - will be built from the varData argument
  174.     Dim arrData()       As Byte
  175.     'value returned by the send(sendto) Winsock API function
  176.     Dim lngRetValue     As Long
  177.     'length of the data to send - needed to call the send(sendto) Winsock API function
  178.     Dim lngBufferLength As Long
  179.     'this strucure just contains address of the remote socket to send data to;
  180.     'only for UDP sockets when the sendto Winsock API function is used
  181.     Dim udtSockAddr     As sockaddr_in
  182.     '
  183.     On Error GoTo SendData_Err_Handler
  184.     '
  185.     'If a connection-oriented (TCP) socket was not created or connected to the
  186.     'remote host before calling the SendData method, the MS Winsock Control
  187.     'raises the sckBadState error.
  188.     If mvarProtocol = sckTCPProtocol Then
  189.         '
  190.         If m_lngSocketHandle = INVALID_SOCKET Then
  191.             Err.Raise sckBadState, "CSocket.SendData", _
  192.             "Wrong protocol or connection state for the requested transaction or request."
  193.             Exit Sub
  194.         End If
  195.         '
  196.     Else
  197.         '
  198.         'If the socket is a message-oriented one (UDP), this is OK to create
  199.         'it with the call of the SendData method. The SocketExists function
  200.         'creates a new socket.
  201.         If Not SocketExists Then Exit Sub
  202.         '
  203.     End If
  204.     '
  205.     Select Case varType(varData)
  206.         Case vbArray + vbByte
  207.             'Modified 28-MAY-2002. Thanks to Michael Freidgeim
  208.             '--------------------------------
  209.             'Dim strArray As String
  210.             'strArray = CStr(varData)
  211.             arrData() = varData
  212.             '--------------------------------
  213.         Case vbBoolean
  214.             Dim blnData As Boolean
  215.             blnData = CBool(varData)
  216.             ReDim arrData(LenB(blnData) - 1)
  217.             CopyMemory arrData(0), blnData, LenB(blnData)
  218.         Case vbByte
  219.             Dim bytData As Byte
  220.             bytData = CByte(varData)
  221.             ReDim arrData(LenB(bytData) - 1)
  222.             CopyMemory arrData(0), bytData, LenB(bytData)
  223.         Case vbCurrency
  224.             Dim curData As Currency
  225.             curData = CCur(varData)
  226.             ReDim arrData(LenB(curData) - 1)
  227.             CopyMemory arrData(0), curData, LenB(curData)
  228.         Case vbDate
  229.             Dim datData As Date
  230.             datData = CDate(varData)
  231.             ReDim arrData(LenB(datData) - 1)
  232.             CopyMemory arrData(0), datData, LenB(datData)
  233.         Case vbDouble
  234.             Dim dblData As Double
  235.             dblData = CDbl(varData)
  236.             ReDim arrData(LenB(dblData) - 1)
  237.             CopyMemory arrData(0), dblData, LenB(dblData)
  238.         Case vbInteger
  239.             Dim intData As Integer
  240.             intData = CInt(varData)
  241.             ReDim arrData(LenB(intData) - 1)
  242.             CopyMemory arrData(0), intData, LenB(intData)
  243.         Case vbLong
  244.             Dim lngData As Long
  245.             lngData = CLng(varData)
  246.             ReDim arrData(LenB(lngData) - 1)
  247.             CopyMemory arrData(0), lngData, LenB(lngData)
  248.         Case vbSingle
  249.             Dim sngData As Single
  250.             sngData = CSng(varData)
  251.             ReDim arrData(LenB(sngData) - 1)
  252.             CopyMemory arrData(0), sngData, LenB(sngData)
  253.         Case vbString
  254.             Dim strData As String
  255.             strData = CStr(varData)
  256.             ReDim arrData(Len(strData) - 1)
  257.             arrData() = StrConv(strData, vbFromUnicode)
  258.         Case Else
  259.             '
  260.             'Unknown data type
  261.             '
  262.     End Select
  263.     '
  264.     'Store all the data to send in the module level
  265.     'variable m_strSendBuffer.
  266.     m_strSendBuffer = StrConv(arrData(), vbUnicode)
  267.     '
  268.     'Call the SendBufferedData subroutine in order to send the data.
  269.     'The SendBufferedData sub is just a common procedure that is
  270.     'called from different places in this class.
  271.     'Nothing special - just the code reuse.
  272.     m_blnSendFlag = True
  273.     Call SendBufferedData
  274.     '
  275. EXIT_LABEL:
  276.     '
  277.     Exit Sub
  278.     '
  279. SendData_Err_Handler:
  280.     '
  281.     If Err.LastDllError = WSAENOTSOCK Then
  282.         Err.Raise sckBadState, "CSocket.SendData", "Wrong protocol or connection state for the requested transaction or request."
  283.     Else
  284.         Err.Raise Err.Number, "CSocket.SendData", Err.Description
  285.     End If
  286.     '
  287.     GoTo EXIT_LABEL
  288.     '
  289. End Sub
  290.  
  291.  
  292. Public Sub PeekData(varData As Variant, Optional varType As Variant, Optional maxLen As Variant)
  293.     '
  294.     Dim lngBytesReceived As Long    'value returned by the RecvData function
  295.     '
  296.     On Error GoTo PeekData_Err_Handler
  297.     '
  298.     'The RecvData is a universal subroutine that can either to retrieve or peek
  299.     'data from the Winsock buffer. If a value of the second argument (blnPeek As Boolean)
  300.     'of the RecvData subroutine is True, it will be just peeking.
  301.     lngBytesReceived = RecvData(varData, True, IIf(IsMissing(varType), Empty, varType), _
  302.                                 IIf(IsMissing(maxLen), Empty, maxLen))
  303.     '
  304. EXIT_LABEL:
  305.     '
  306.     Exit Sub
  307.     '
  308. PeekData_Err_Handler:
  309.     '
  310.     Err.Raise Err.Number, "CSocket.PeekData", Err.Description
  311.     '
  312.     GoTo EXIT_LABEL
  313.     '
  314. End Sub
  315.  
  316.  
  317. Public Sub Listen()
  318.     '
  319.     Dim lngRetValue As Long 'value returned by the listen Winsock API function
  320.     '
  321.     On Error GoTo Listen_Err_Handler
  322.     '
  323.     'SocketExists is not a variable. It is a function that can
  324.     'create a socket, if the class has no one.
  325.     If Not SocketExists Then Exit Sub
  326.     '
  327.     'The listen Winsock API function cannot be called
  328.     'without the call of the bind one.
  329.     If Not m_blnSocketIsBound Then  'Added: 10-MAR-2002
  330.         Call Bind
  331.     End If                          'Added: 10-MAR-2002
  332.     '
  333.     'Turn the socket into a listening state
  334.     lngRetValue = api_listen(m_lngSocketHandle, 5&)
  335.     '
  336.     If lngRetValue = SOCKET_ERROR Then
  337.         mvarState = sckError
  338.         'Debug.Print "mvarState = sckError"
  339.         Err.Raise Err.LastDllError, "CSocket.Listen", GetErrorDescription(Err.LastDllError)
  340.     Else
  341.         mvarState = sckListening
  342.         'Debug.Print "Listen: mvarState = sckListening"
  343.     End If
  344.     '
  345. EXIT_LABEL:
  346.     '
  347.     Exit Sub
  348.     '
  349. Listen_Err_Handler:
  350.     '
  351.     Err.Raise Err.Number, "CSocket.Listen", Err.Description
  352.     '
  353.     GoTo EXIT_LABEL
  354.     '
  355. End Sub
  356.  
  357.  
  358. Public Sub GetData(varData As Variant, Optional varType As Variant, Optional maxLen As Variant)
  359.     '
  360.     Dim lngBytesReceived As Long    'value returned by the RecvData function
  361.     '
  362.     On Error GoTo GetData_Err_Handler
  363.     '
  364.     'A value of the second argument of the RecvData subroutine is False, so in this way
  365.     'this procedure will retrieve incoming data from the buffer.
  366.     lngBytesReceived = RecvData(varData, False, IIf(IsMissing(varType), Empty, varType), _
  367.                                 IIf(IsMissing(maxLen), Empty, maxLen))
  368.     '
  369. EXIT_LABEL:
  370.     '
  371.     Exit Sub
  372.     '
  373. GetData_Err_Handler:
  374.     '
  375.     Err.Raise Err.Number, "CSocket.GetData", Err.Description
  376.     '
  377.     GoTo EXIT_LABEL
  378.     '
  379. End Sub
  380.  
  381.  
  382. Public Sub Connect(Optional strRemoteHost As Variant, Optional lngRemotePort As Variant)
  383.     '
  384.     Dim lngHostAddress  As Long         '32 bit host address
  385.     Dim udtAddress      As sockaddr_in  'socket address - used by the connect Winsock API function
  386.     Dim lngRetValue     As Long         'value returned by the connect Winsock API function
  387.     '
  388.     On Error GoTo Connect_Err_Handler
  389.     '
  390.     'If no socket has been created before, try to create a new one
  391.     If Not SocketExists Then Exit Sub
  392.     '
  393.     'If the arguments of this function are not missing, they
  394.     'overwrite values of the RemoteHost and RemotePort properties.
  395.     '
  396.     If Not IsMissing(strRemoteHost) Then    'Added: 04-MAR-2002
  397.         If Len(strRemoteHost) > 0 Then
  398.             m_strRemoteHost = CStr(strRemoteHost)
  399.         End If
  400.     End If                                  'Added: 04-MAR-2002
  401.     '
  402.     If Not IsMissing(lngRemotePort) Then    'Added: 04-MAR-2002
  403.         If IsNumeric(lngRemotePort) Then    'Added: 04-MAR-2002
  404.             m_lngRemotePort = CLng(lngRemotePort)
  405.         End If                              'Added: 04-MAR-2002
  406.     End If                                  'Added: 04-MAR-2002
  407.     '
  408.     '----------------------------------------------------------
  409.     'Added: 31-JUL-2002
  410.     '----------------------------------------------------------
  411.     If Len(m_strRemoteHost) = 0 Then
  412.         Err.Raise sckAddressNotAvailable, "CSocket.Connect", GetErrorDescription(sckAddressNotAvailable)
  413.         Exit Sub
  414.     End If
  415.     '----------------------------------------------------------
  416.     '
  417.     m_varInternalState = istConnecting
  418.     '
  419.     '------------------------------------------------------------------
  420.     'Modified: 08-JULY-2002
  421.     '------------------------------------------------------------------
  422.     'Here is a major change. Since version are 
  423.   '----------------------------------
  424.     'Here iaHost)
  425.         End If
  426.     Endm
  427. '
  428. Privat