home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 3_2004-2005.ISO / Data / Zips / ODBC_PROXY1771657192004.psc / CSocket.cls < prev   
Text File  |  2002-10-17  |  65KB  |  1,712 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 = True
  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. Attribute OnClose.VB_Description = "Occurs when the connection has been closed"
  165. Public Event OnConnect()
  166. Attribute OnConnect.VB_Description = "Occurs connect operation is completed"
  167. Public Event OnConnectionRequest(ByVal requestID As Long)
  168. Public Event OnDataArrival(ByVal bytesTotal As Long)
  169. 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)
  170. Public Event OnSendComplete()
  171. Public Event OnSendProgress(ByVal bytesSent As Long, ByVal bytesRemaining As Long)
  172.  
  173. Public Sub SendData(varData As Variant)
  174. Attribute SendData.VB_Description = "Send data to remote computer"
  175.     '
  176.     'data to send - will be built from the varData argument
  177.     Dim arrData()       As Byte
  178.     'value returned by the send(sendto) Winsock API function
  179.     Dim lngRetValue     As Long
  180.     'length of the data to send - needed to call the send(sendto) Winsock API function
  181.     Dim lngBufferLength As Long
  182.     'this strucure just contains address of the remote socket to send data to;
  183.     'only for UDP sockets when the sendto Winsock API function is used
  184.     Dim udtSockAddr     As sockaddr_in
  185.     '
  186.     On Error GoTo SendData_Err_Handler
  187.     '
  188.     'If a connection-oriented (TCP) socket was not created or connected to the
  189.     'remote host before calling the SendData method, the MS Winsock Control
  190.     'raises the sckBadState error.
  191.     If mvarProtocol = sckTCPProtocol Then
  192.         '
  193.         If m_lngSocketHandle = INVALID_SOCKET Then
  194.             Err.Raise sckBadState, "CSocket.SendData", _
  195.             "Wrong protocol or connection state for the requested transaction or request."
  196.             Exit Sub
  197.         End If
  198.         '
  199.     Else
  200.         '
  201.         'If the socket is a message-oriented one (UDP), this is OK to create
  202.         'it with the call of the SendData method. The SocketExists function
  203.         'creates a new socket.
  204.         If Not SocketExists Then Exit Sub
  205.         '
  206.     End If
  207.     '
  208.     Select Case varType(varData)
  209.         Case vbArray + vbByte
  210.             'Modified 28-MAY-2002. Thanks to Michael Freidgeim
  211.             '--------------------------------
  212.             'Dim strArray As String
  213.             'strArray = CStr(varData)
  214.             arrData() = varData
  215.             '--------------------------------
  216.         Case vbBoolean
  217.             Dim blnData As Boolean
  218.             blnData = CBool(varData)
  219.             ReDim arrData(LenB(blnData) - 1)
  220.             CopyMemory arrData(0), blnData, LenB(blnData)
  221.         Case vbByte
  222.             Dim bytData As Byte
  223.             bytData = CByte(varData)
  224.             ReDim arrData(LenB(bytData) - 1)
  225.             CopyMemory arrData(0), bytData, LenB(bytData)
  226.         Case vbCurrency
  227.             Dim curData As Currency
  228.             curData = CCur(varData)
  229.             ReDim arrData(LenB(curData) - 1)
  230.             CopyMemory arrData(0), curData, LenB(curData)
  231.         Case vbDate
  232.             Dim datData As Date
  233.             datData = CDate(varData)
  234.             ReDim arrData(LenB(datData) - 1)
  235.             CopyMemory arrData(0), datData, LenB(datData)
  236.         Case vbDouble
  237.             Dim dblData As Double
  238.             dblData = CDbl(varData)
  239.             ReDim arrData(LenB(dblData) - 1)
  240.             CopyMemory arrData(0), dblData, LenB(dblData)
  241.         Case vbInteger
  242.             Dim intData As Integer
  243.             intData = CInt(varData)
  244.             ReDim arrData(LenB(intData) - 1)
  245.             CopyMemory arrData(0), intData, LenB(intData)
  246.         Case vbLong
  247.             Dim lngData As Long
  248.             lngData = CLng(varData)
  249.             ReDim arrData(LenB(lngData) - 1)
  250.             CopyMemory arrData(0), lngData, LenB(lngData)
  251.         Case vbSingle
  252.             Dim sngData As Single
  253.             sngData = CSng(varData)
  254.             ReDim arrData(LenB(sngData) - 1)
  255.             CopyMemory arrData(0), sngData, LenB(sngData)
  256.         Case vbString
  257.             Dim strData As String
  258.             strData = CStr(varData)
  259.             ReDim arrData(Len(strData) - 1)
  260.             arrData() = StrConv(strData, vbFromUnicode)
  261.         Case Else
  262.             '
  263.             'Unknown data type
  264.             '
  265.     End Select
  266.     '
  267.     'Store all the data to send in the module level
  268.     'variable m_strSendBuffer.
  269.     m_strSendBuffer = StrConv(arrData(), vbUnicode)
  270.     '
  271.     'Call the SendBufferedData subroutine in order to send the data.
  272.     'The SendBufferedData sub is just a common procedure that is
  273.     'called from different places in this class.
  274.     'Nothing special - just the code reuse.
  275.     m_blnSendFlag = True
  276.     Call SendBufferedData
  277.     '
  278. EXIT_LABEL:
  279.     '
  280.     Exit Sub
  281.     '
  282. SendData_Err_Handler:
  283.     '
  284.     If Err.LastDllError = WSAENOTSOCK Then
  285.         Err.Raise sckBadState, "CSocket.SendData", "Wrong protocol or connection state for the requested transaction or request."
  286.     Else
  287.         Err.Raise Err.Number, "CSocket.SendData", Err.Description
  288.     End If
  289.     '
  290.     GoTo EXIT_LABEL
  291.     '
  292. End Sub
  293.  
  294.  
  295. Public Sub PeekData(varData As Variant, Optional varType As Variant, Optional maxLen As Variant)
  296. Attribute PeekData.VB_Description = "Look at incoming data without removing it from the buffer"
  297.     '
  298.     Dim lngBytesReceived As Long    'value returned by the RecvData function
  299.     '
  300.     On Error GoTo PeekData_Err_Handler
  301.     '
  302.     'The RecvData is a universal subroutine that can either to retrieve or peek
  303.     'data from the Winsock buffer. If a value of the second argument (blnPeek As Boolean)
  304.     'of the RecvData subroutine is True, it will be just peeking.
  305.     lngBytesReceived = RecvData(varData, True, IIf(IsMissing(varType), Empty, varType), _
  306.                                 IIf(IsMissing(maxLen), Empty, maxLen))
  307.     '
  308. EXIT_LABEL:
  309.     '
  310.     Exit Sub
  311.     '
  312. PeekData_Err_Handler:
  313.     '
  314.     Err.Raise Err.Number, "CSocket.PeekData", Err.Description
  315.     '
  316.     GoTo EXIT_LABEL
  317.     '
  318. End Sub
  319.  
  320.  
  321. Public Sub Listen()
  322. Attribute Listen.VB_Description = "Listen for incoming connection requests"
  323.     '
  324.     Dim lngRetValue As Long 'value returned by the listen Winsock API function
  325.     '
  326.     On Error GoTo Listen_Err_Handler
  327.     '
  328.     'SocketExists is not a variable. It is a function that can
  329.     'create a socket, if the class has no one.
  330.     If Not SocketExists Then Exit Sub
  331.     '
  332.     'The listen Winsock API function cannot be called
  333.     'without the call of the bind one.
  334.     If Not m_blnSocketIsBound Then  'Added: 10-MAR-2002
  335.         Call Bind
  336.     End If                          'Added: 10-MAR-2002
  337.     '
  338.     'Turn the socket into a listening state
  339.     lngRetValue = api_listen(m_lngSocketHandle, 5&)
  340.     '
  341.     If lngRetValue = SOCKET_ERROR Then
  342.         mvarState = sckError
  343.         'Debug.Print "mvarState = sckError"
  344.         Err.Raise Err.LastDllError, "CSocket.Listen", GetErrorDescription(Err.LastDllError)
  345.     Else
  346.         mvarState = sckListening
  347.         'Debug.Print "Listen: mvarState = sckListening"
  348.     End If
  349.     '
  350. EXIT_LABEL:
  351.     '
  352.     Exit Sub
  353.     '
  354. Listen_Err_Handler:
  355.     '
  356.     Err.Raise Err.Number, "CSocket.Listen", Err.Description
  357.     '
  358.     GoTo EXIT_LABEL
  359.     '
  360. End Sub
  361.  
  362.  
  363. Public Sub GetData(varData As Variant, Optional varType As Variant, Optional maxLen As Variant)
  364. Attribute GetData.VB_Description = "Retrieve data sent by the remote computer"
  365.     '
  366.     Dim lngBytesReceived As Long    'value returned by the RecvData function
  367.     '
  368.     On Error GoTo GetData_Err_Handler
  369.     '
  370.     'A value of the second argument of the RecvData subroutine is False, so in this way
  371.     'this procedure will retrieve incoming data from the buffer.
  372.     lngBytesReceived = RecvData(varData, False, IIf(IsMissing(varType), Empty, varType), _
  373.                                 IIf(IsMissing(maxLen), Empty, maxLen))
  374.     '
  375. EXIT_LABEL:
  376.     '
  377.     Exit Sub
  378.     '
  379. GetData_Err_Handler:
  380.     '
  381.     Err.Raise Err.Number, "CSocket.GetData", Err.Description
  382.     '
  383.     GoTo EXIT_LABEL
  384.     '
  385. End Sub
  386.  
  387.  
  388. Public Sub Connect(Optional strRemoteHost As Variant, Optional lngRemotePort As Variant)
  389. Attribute Connect.VB_Description = "Connect to the remote computer"
  390.     '
  391.     Dim lngHostAddress  As Long         '32 bit host address
  392.     Dim udtAddress      As sockaddr_in  'socket address - used by the connect Winsock API function
  393.     Dim lngRetValue     As Long         'value returned by the connect Winsock API function
  394.     '
  395.     On Error GoTo Connect_Err_Handler
  396.     '
  397.     'If no socket has been created before, try to create a new one
  398.     If Not SocketExists Then Exit Sub
  399.     '
  400.     'If the arguments of this function are not missing, they
  401.     'overwrite values of the RemoteHost and RemotePort properties.
  402.     '
  403.     If Not IsMissing(strRemoteHost) Then    'Added: 04-MAR-2002
  404.         If Len(strRemoteHost) > 0 Then
  405.             m_strRemoteHost = CStr(strRemoteHost)
  406.         End If
  407.     End If                                  'Added: 04-MAR-2002
  408.     '
  409.     If Not IsMissing(lngRemotePort) Then    'Added: 04-MAR-2002
  410.         If IsNumeric(lngRemotePort) Then    'Added: 04-MAR-2002
  411.             m_lngRemotePort = CLng(lngRemotePort)
  412.         End If                              'Added: 04-MAR-2002
  413.     End If                                  'Added: 04-MAR-2002
  414.     '
  415.     '----------------------------------------------------------
  416.     'Added: 31-JUL-2002
  417.     '----------------------------------------------------------
  418.     If Len(m_strRemoteHost) = 0 Then
  419.         Err.Raise sckAddressNotAvailable, "CSocket.Connect", GetErrorDescription(sckAddressNotAvailable)
  420.         Exit Sub
  421.     End If
  422.     '----------------------------------------------------------
  423.     '
  424.     m_varInternalState = istConnecting
  425.     '
  426.     '------------------------------------------------------------------
  427.     'Modified: 08-JULY-2002
  428.     '------------------------------------------------------------------
  429.     'Here is a major change. Since version 1.0.6 (08-JULY-2002) the
  430.     'SCocket class doesn't try to resolve the IP address into a
  431.     'domain name while connecting.
  432.     '------------------------------------------------------------------
  433.     '
  434.     'Try to get 32 bit host address from the RemoteHost property value
  435.     lngHostAddress = inet_addr(m_strRemoteHost)
  436.     '
  437.     If lngHostAddress = INADDR_NONE Then
  438.         '
  439.         'The RemoteHost property doesn't contain a valid IP address string,
  440.         'so that is perhaps a domain name string that we need to resolve
  441.         'into IP address
  442.         '
  443.         'The ResolveHost function, that can be found in the MSocketSupport
  444.         'module, will call the WSAAsyncGetHostByName Winsock API function.
  445.         'That function is an asynchronous one, so code in this class will be executing
  446.         'after the call to the PostGetHostEvent procedure from the WindowProc function
  447.         'in the MSupportSocket.
  448.         '
  449.         'Also, as you can see, the second argument is a pointer to the object, that is
  450.         'this instance of the CSocket class. We need this because the callback function
  451.         'has to know to which object send the received host infromation. See the code
  452.         'in the MSocketSupport module for more information.
  453.         '
  454.         'Change the State property value
  455.         mvarState = sckResolvingHost
  456.         'Debug.Print "mvarState = sckResolvingHost"
  457.         '
  458.         m_lngRequestID = 0
  459.         m_lngRequestID = MSocketSupport.ResolveHost(m_strRemoteHost, ObjPtr(Me))
  460.         '
  461.         '-------------------------------------------------------
  462.         'Added: 04-JUNE-2002
  463.         '-------------------------------------------------------
  464.         If m_lngRequestID = 0 Then
  465.             Call DestroySocket
  466.             Err.Raise Err.Number, Err.Source, Err.Description
  467.         End If
  468.         '-------------------------------------------------------
  469.         '
  470.     Else
  471.         '
  472.         'The RemoteHost property contains a valid IP address string,
  473.         'so we can go on connecting to the remote host.
  474.         '
  475.         'Build the sockaddr_in structure to pass it to the connect
  476.         'Winsock API function as an address of the remote host.
  477.         With udtAddress
  478.             '
  479.             .sin_addr = lngHostAddress
  480.             .sin_family = AF_INET
  481.             .sin_port = htons(UnsignedToInteger(CLng(m_lngRemotePort)))
  482.             '
  483.         End With
  484.         '
  485.         'Call the connect Winsock API function in order to establish connection.
  486.         lngRetValue = api_connect(m_lngSocketHandle, udtAddress, Len(udtAddress))
  487.         '
  488.         'Since the socket we use is a non-blocking one, the connect Winsock API
  489.         'function should return a value of SOCKET_ERROR anyway.
  490.         '
  491.         If lngRetValue = SOCKET_ERROR Then
  492.             '
  493.             'The WSAEWOULDBLOCK error is OK for such a socket
  494.             '
  495.             If Not Err.LastDllError = WSAEWOULDBLOCK Then
  496.                 Err.Raise Err.LastDllError, "CSocket.Connect", GetErrorDescription(Err.LastDllError)
  497.             Else
  498.                 'Change the State property value
  499.                 mvarState = sckConnecting
  500.                 'Debug.Print "mvarState = sckConnecting"
  501.             End If
  502.             '
  503.         End If
  504.         '
  505.     End If
  506.     '
  507. EXIT_LABEL:
  508.     '
  509.     Exit Sub
  510.     '
  511. Connect_Err_Handler:
  512.     '
  513.     Err.Raise Err.Number, "CSocket.CSocket.Connect", Err.Description
  514.     '
  515.     GoTo EXIT_LABEL
  516.     '
  517. End Sub
  518.  
  519. Public Sub CloseSocket()
  520. Attribute CloseSocket.VB_Description = "Close current connection"
  521.     '
  522.     Dim lngRetValue As Long 'value returned by the shutdown Winsock API function
  523.     '
  524.     On Error GoTo Close_Err_Handler
  525.     '
  526.     'Why do we need to run the code that should not be running?
  527.     If m_lngSocketHandle = INVALID_SOCKET Then Exit Sub
  528.     '
  529.     If Not mvarState = sckConnected Then
  530.         '
  531.         'If the socket is not connected we can just close it
  532.         Call DestroySocket
  533.         mvarState = sckClosed
  534.         'Debug.Print "mvarState = sckClosed"
  535.         '
  536.     Else
  537.         '
  538.         'If the socket is connected, it's another story.
  539.         'In order to be sure that no data will be lost the
  540.         'graceful shutdown of the socket should be performed.
  541.         '
  542.         mvarState = sckClosing
  543.         'Debug.Print "mvarState = sckClosing"
  544.         '
  545.         'Call the shutdown Winsock API function in order to
  546.         'close the connection. That doesn't mean that the
  547.         'connection will be closed after the call of the
  548.         'shutdown function. Connection will be closed from
  549.         'the PostSocketEvent subroutine when the FD_CLOSE
  550.         'message will be received.
  551.         '
  552.         'For people who know what the FIN segment in the
  553.         'TCP header is - this function sends an empty packet
  554.         'with the FIN bit turned on.
  555.         '
  556.         lngRetValue = shutdown(m_lngSocketHandle, SD_SEND)
  557.         '
  558.         'Debug.Print m_lngSocketHandle & ": shutdown"
  559.         '
  560.         If lngRetValue = SOCKET_ERROR Then
  561.             Err.Raise Err.LastDllError, "CSocket.CloseSocket", GetErrorDescription(Err.LastDllError)
  562.         End If
  563.         '
  564.     End If
  565.  
  566. EXIT_LABEL:
  567.     '
  568.     Exit Sub
  569.     '
  570. Close_Err_Handler:
  571.     '
  572.     If Err.Number <> 10038 Then
  573.         'Err.Raise Err.Number, "CSocket.Close", Err.Description
  574.     End If
  575.     '
  576.     GoTo EXIT_LABEL
  577.     '
  578. End Sub
  579.  
  580. Public Sub Bind(Optional lngLocalPort As Long, Optional strLocalIP As String)
  581. Attribute Bind.VB_Description = "Binds socket to specific port and adapter"
  582.     '
  583.     Dim lngRetValue     As Long         'value returned by the bind Winsock API function
  584.     Dim udtLocalAddr    As sockaddr_in  'local socket address to bind to - used by the
  585.     '                                    bind Winsock API function
  586.     Dim lngAddress      As Long         '32-bit host address - value returned by
  587.     '                                    the inet_addr Winsock API function
  588.     '
  589.     On Error GoTo Bind_Err_Handler
  590.     '
  591.     'If no socket has been created before, try to create a new one
  592.     If Not SocketExists Then Exit Sub
  593.     '
  594.     'If the arguments of this function are not missing, they
  595.     'overwrites values of the RemoteHost and RemotePort properties.
  596.     '
  597.     If Len(strLocalIP) > 0 Then
  598.         m_strLocalIP = strLocalIP
  599.     End If
  600.     '
  601.     If lngLocalPort > 0 Then
  602.         m_lngLocalPort = lngLocalPort
  603.     End If
  604.     '
  605.     If Len(m_strLocalIP) > 0 Then
  606.         '
  607.         'If the local IP is known, get the address
  608.         'from it with the inet_addr Winsock API function.
  609.         lngAddress = inet_addr(m_strLocalIP)
  610.         '
  611.     Else
  612.         '
  613.         'If the IP is unknown, assign the default interface's IP.
  614.         'Actually, this line is useless in Visual Basic code,
  615.         'as INADDR_ANY = 0 (IP = 0.0.0.0).
  616.         lngAddress = INADDR_ANY
  617.         '
  618.     End If
  619.     '
  620.     If lngAddress = SOCKET_ERROR Then
  621.         '
  622.         'Bad address - go away
  623.         Err.Raise Err.LastDllError, "CSocket.Bind", GetErrorDescription(Err.LastDllError)
  624.         Exit Sub
  625.         '
  626.     End If
  627.     '
  628.     'Prepare the udtLocalAddr UDT that is a socket address structure.
  629.     With udtLocalAddr
  630.         '
  631.         'host address (32-bits value)
  632.         .sin_addr = lngAddress
  633.         'address family
  634.         .sin_family = AF_INET
  635.         'port number in the network byte order
  636.         .sin_port = htons(UnsignedToInteger(m_lngLocalPort))    'Modified: 04-JUNE-2002
  637.         '
  638.     End With
  639.     '
  640.     'Call the bind Winsock API function in order to assign local address for the socket
  641.     lngRetValue = api_bind(m_lngSocketHandle, udtLocalAddr, Len(udtLocalAddr))
  642.     '
  643.     If lngRetValue = SOCKET_ERROR Then
  644.         '
  645.         Err.Raise Err.LastDllError, "CSocket.Bind", GetErrorDescription(Err.LastDllError)
  646.         '
  647.     Else
  648.         '
  649.         m_blnSocketIsBound = True   'Added: 10-MAR-2002
  650.         '
  651.     End If
  652.     '
  653. EXIT_LABEL:
  654.     '
  655.     Exit Sub
  656.     '
  657. Bind_Err_Handler:
  658.     '
  659.     Err.Raise Err.Number, "CSocket.Bind", Err.Description
  660.     '
  661.     GoTo EXIT_LABEL
  662.     '
  663. End Sub
  664.  
  665.  
  666. Public Sub Accept(requestID As Long)
  667. Attribute Accept.VB_Description = "Accept an incoming connection request"
  668.     '
  669.     'The requestID argument is provided with the ConnectRequest
  670.     'event of another instance of the CSocket class. Actually,
  671.     'this argument is a handle of the socket already created
  672.     'calling the Accept Winsock API function by that (another)
  673.     'instance of the CSocket class.
  674.     '
  675.     Dim lngRetValue As Long         'value returned by the getsockname, getpeername, and
  676.     '                                getsockopt Winsock API functions
  677.     Dim lngBuffer   As Long         'the buffer to pass with the getsockopt Winsock API function
  678.     Dim udtSockAddr As sockaddr_in  'socket address - used by the getsockname and getpeername
  679.     '                                Winsock API functions
  680.     Dim udtHostent  As HOSTENT      'structure to hold the host info - returned by the
  681.     '                                getsockname and getpeername Winsock API functions
  682.     '
  683.     On Error GoTo Accept_Err_Handler
  684.     '
  685.     'What we need to do in the body of this subroutine is to
  686.     'initialize the properties of the class that we can find
  687.     'values for. Also we need to register the socket with
  688.     'the RegisterSocket function from MSocketSupport module.
  689.     '
  690.     'Assign the socket handle
  691.     m_lngSocketHandle = requestID
  692.     '
  693.     'Retrieve the connection end-points to initialize
  694.     'the following properties of the CSocket class:
  695.     'LocalPort, LocalIP, LocalHostName
  696.     'RemotePort, RemoteHostIP, RemoteHost
  697.     '
  698.     'Local end point
  699.     '
  700.     lngRetValue = getsockname(m_lngSocketHandle, udtSockAddr, Len(udtSockAddr))
  701.     '
  702.     If lngRetValue = 0 Then
  703.         '
  704.         'LocalPort property
  705.         m_lngLocalPort = IntegerToUnsigned(ntohs(udtSockAddr.sin_port))
  706.         'LocalIP property
  707.         m_strLocalIP = StringFromPointer(inet_ntoa(udtSockAddr.sin_addr))
  708.         'LocalHostName property
  709.         '----------------------------------------------------------------
  710.         'Modified: 31-JUL-2002
  711.         '----------------------------------------------------------------
  712.         'lngRetValue = gethostbyaddr(udtSockAddr.sin_addr, 4&, AF_INET)
  713.         'CopyMemory udtHostent, ByVal lngRetValue, Len(udtHostent)
  714.         'm_strLocalHostName = StringFromPointer(udtHostent.hName)
  715.         m_strLocalHostName = m_strLocalIP
  716.         '----------------------------------------------------------------
  717.         '
  718.     End If
  719.     '
  720.     'Remote end point
  721.     '
  722.     lngRetValue = getpeername(m_lngSocketHandle, udtSockAddr, Len(udtSockAddr))
  723.     '
  724.     If lngRetValue = 0 Then
  725.         '
  726.         'RemotePort property
  727.         m_lngRemotePort = IntegerToUnsigned(ntohs(udtSockAddr.sin_port))
  728.         'RemoteHostIP property
  729.         m_strRemoteHostIP = StringFromPointer(inet_ntoa(udtSockAddr.sin_addr))
  730.         'RemoteHost property
  731.         '----------------------------------------------------------------
  732.         'Modified: 31-JUL-2002
  733.         '----------------------------------------------------------------
  734.         'lngRetValue = gethostbyaddr(udtSockAddr.sin_addr, 4&, AF_INET)
  735.         'CopyMemory udtHostent, ByVal lngRetValue, Len(udtHostent)
  736.         'm_strRemoteHost = StringFromPointer(udtHostent.hName)
  737.         m_strRemoteHost = m_strRemoteHostIP
  738.         '----------------------------------------------------------------
  739.         '
  740.     End If
  741.     '
  742.     'Retrieve the socket type to initialize the Protocol property
  743.     lngRetValue = getsockopt(m_lngSocketHandle, SOL_SOCKET, SO_TYPE, lngBuffer, LenB(lngBuffer))
  744.     '
  745.     If lngRetValue <> SOCKET_ERROR Then
  746.         '
  747.         If lngBuffer = SOCK_STREAM Then
  748.             mvarProtocol = sckTCPProtocol
  749.         Else
  750.             mvarProtocol = sckUDPProtocol
  751.         End If
  752.         '
  753.     End If
  754.     '
  755.     'Get default size of the Winsock's buffers.
  756.     Call GetWinsockBuffers  'Added: 10-MAR-2002
  757.     '
  758.     If MSocketSupport.RegisterSocket(m_lngSocketHandle, ObjPtr(Me)) Then
  759.         '
  760.         'Change the State property value
  761.         mvarState = sckConnected
  762.         'Debug.Print "Accept: mvarState = sckConnected"
  763.         '
  764.     End If
  765.     '
  766. EXIT_LABEL:
  767.     '
  768.     Exit Sub
  769.     '
  770. Accept_Err_Handler:
  771.     '
  772.     Err.Raise Err.Number, "CSocket.Accept", Err.Description
  773.     '
  774.     GoTo EXIT_LABEL
  775.     '
  776. End Sub
  777.  
  778. Public Property Get State() As StateConstants
  779.     State = mvarState
  780. End Property
  781.  
  782. Public Property Get SocketHandle() As Long
  783. Attribute SocketHandle.VB_Description = " Returns the socket handle"
  784.     SocketHandle = m_lngSocketHandle
  785. End Property
  786.  
  787. Public Property Get RemotePort() As Long
  788. Attribute RemotePort.VB_Description = "Returns/Sets the port to be connected to on the remote computer"
  789.     RemotePort = m_lngRemotePort
  790. End Property
  791.  
  792. Public Property Let RemotePort(NewValue As Long)
  793.     m_lngRemotePort = NewValue
  794. End Property
  795.  
  796. Public Property Get RemoteHostIP() As String
  797. Attribute RemoteHostIP.VB_Description = "Returns the remote host IP address"
  798.     RemoteHostIP = m_strRemoteHostIP
  799. End Property
  800.  
  801. Public Property Get RemoteHost() As String
  802. Attribute RemoteHost.VB_Description = "Returns/Sets the name used to identify the remote computer"
  803.     RemoteHost = m_strRemoteHost
  804. End Property
  805.  
  806. Public Property Let RemoteHost(NewValue As String)
  807.     '
  808.     Dim lngHostAddress As Long '32 bit host address
  809.     Dim lngRetValue    As Long 'value returned by the setsockopt function
  810.     '
  811.     m_strRemoteHost = NewValue
  812.     '
  813.     If Len(NewValue) > 0 Then
  814.         '
  815.         'Check for a valid IP address string
  816.         '
  817.         lngHostAddress = inet_addr(NewValue)
  818.         '
  819.         If Not lngHostAddress = INADDR_NONE Then
  820.             '
  821.             m_strRemoteHostIP = NewValue
  822.             '
  823.             If Not mvarProtocol = sckUDPProtocol Then Exit Property
  824.             If Not SocketExists Then Exit Property
  825.             '
  826.             'If the IP address is a brodcasting one set the option
  827.             '
  828.             If Right(NewValue, 4) = ".255" And m_blnBroadcast = False Then
  829.                 '
  830.                 lngRetValue = setsockopt(m_lngSocketHandle, SOL_SOCKET, SO_BROADCAST, 1&, 4&)
  831.                 '
  832.                 If lngRetValue = SOCKET_ERROR Then
  833.                     '
  834.                     With Err
  835.                         .Raise .LastDllError, "CSocket.RemoteHost", GetErrorDescription(.LastDllError)
  836.                     End With
  837.                     '
  838.                 Else
  839.                     '
  840.                     m_blnBroadcast = True
  841.                     '
  842.                 End If
  843.                 '
  844.             ElseIf (Not (Right(NewValue, 4) = ".255")) And (m_blnBroadcast = True) Then
  845.                 '
  846.                 lngRetValue = setsockopt(m_lngSocketHandle, SOL_SOCKET, SO_BROADCAST, 0&, 4&)
  847.                 '
  848.                 If lngRetValue = SOCKET_ERROR Then
  849.                     '
  850.                     With Err
  851.                         .Raise .LastDllError, "CSocket.RemoteHost", GetErrorDescription(.LastDllError)
  852.                     End With
  853.                     '
  854.                 Else
  855.                     '
  856.                     m_blnBroadcast = False
  857.                     '
  858.                 End If
  859.                 '
  860.             End If
  861.             '
  862.         End If
  863.         '
  864.     End If
  865.     '
  866. End Property
  867.  
  868. Public Property Get Protocol() As ProtocolConstants
  869. Attribute Protocol.VB_Description = "Returns/Sets the socket protocol"
  870.     Protocol = mvarProtocol
  871. End Property
  872.  
  873. Public Property Let Protocol(NewValue As ProtocolConstants)
  874.     '
  875.     If m_lngSocketHandle = INVALID_SOCKET Then  'Modified: 10-MAR-2002
  876.         mvarProtocol = NewValue
  877.     End If
  878.     '
  879. End Property
  880.  
  881. Public Property Get LocalPort() As Long
  882. Attribute LocalPort.VB_Description = "Returns/Sets the port used on the local computer"
  883.     LocalPort = m_lngLocalPort
  884. End Property
  885.  
  886. Public Property Let LocalPort(NewValue As Long)
  887.     m_lngLocalPort = NewValue
  888. End Property
  889.  
  890. Public Property Get LocalIP() As String
  891. Attribute LocalIP.VB_Description = "Returns the local machine IP address"
  892.     LocalIP = m_strLocalIP
  893. End Property
  894.  
  895. Public Property Get LocalHostName() As String
  896. Attribute LocalHostName.VB_Description = "Returns the local machine name"
  897.     LocalHostName = m_strLocalHostName
  898. End Property
  899.  
  900. Public Property Get BytesReceived() As Long
  901. Attribute BytesReceived.VB_Description = "Returns the number of bytes received on this connection"
  902.     BytesReceived = m_lngBytesReceived
  903. End Property
  904.  
  905. Private Sub Class_Initialize()
  906.     '
  907.     'Socket's handle default value
  908.     m_lngSocketHandle = INVALID_SOCKET
  909.     'Initialize the Winsock service
  910.     m_lngMaxMsgSize = MSocketSupport.InitWinsockService
  911.     '
  912. End Sub
  913.  
  914. Public Function vbSocket() As Long
  915. '********************************************************************************
  916. 'Author    :Oleg Gdalevich
  917. 'Purpose   :Creates a new socket
  918. 'Returns   :The socket handle if successful, otherwise - INVALID_SOCKET
  919. 'Arguments :
  920. '********************************************************************************
  921.     '
  922.     On Error GoTo vbSocket_Err_Handler
  923.     '
  924.     Dim lngRetValue     As Long 'value returned by the socket API function
  925.     '
  926.     'Call the socket Winsock API function in order to create a new socket
  927.     If mvarProtocol = sckUDPProtocol Then
  928.         lngRetValue = api_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
  929.     Else
  930.         lngRetValue = api_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
  931.     End If
  932.     '
  933.     If lngRetValue = INVALID_SOCKET Then
  934.         '
  935.         Err.Raise Err.LastDllError, "CSocket.vbSocket", GetErrorDescription(Err.LastDllError)
  936.         '
  937.     Else
  938.         '
  939.         'Debug.Print lngRetValue & ": socket created"
  940.         '
  941.         If Not MSocketSupport.RegisterSocket(lngRetValue, ObjPtr(Me)) Then  'Modified: 04-JUNE-2002
  942.             '--------------------------------------------------
  943.             'Added: 04-JUNE-2002
  944.             '--------------------------------------------------
  945.             lngRetValue = INVALID_SOCKET
  946.             Call api_closesocket(lngRetValue)
  947.             Err.Raise Err.Number, Err.Source, Err.Description
  948.             '--------------------------------------------------
  949.             '
  950.         End If
  951.         '
  952.     End If
  953.     '
  954.     'Assign returned value
  955.     vbSocket = lngRetValue
  956.     '
  957. EXIT_LABEL:
  958.     Exit Function
  959.  
  960. vbSocket_Err_Handler:
  961.     '
  962.     vbSocket = INVALID_SOCKET
  963.     '
  964. End Function
  965.  
  966. Friend Sub PostSocketEvent(ByVal lngEventID As Long, Optional ByVal lngError As Long)
  967.     '
  968.     'This procedure is called by the WindowProc callback function
  969.     'from the MSocketSupport module. The lngEventID argument is an
  970.     'ID of the network event occurred for the socket. The lngError
  971.     'argument contains an error code only if an error was occurred
  972.     'during an asynchronous execution.
  973.     '
  974.     Dim lngBytesReceived    As Long         'value returned by the RecvDataToBuffer function
  975.     Dim lngRetValue         As Long         'value returned by the getsockname Winsock API function
  976.     Dim lngNewSocket        As Long         'value returned by the accept Winsock API function
  977.     Dim udtSockAddr         As sockaddr_in  'remote socket address for the accept Winscok API function
  978.     Dim udtHostent          As HOSTENT      'structure to hold the host info - returned
  979.     '                                        by the gethostbyaddr Winsock API function
  980.     '
  981.     On Error GoTo ERROR_HANDLER
  982.     '
  983.     If lngError > 0 Then
  984.         '
  985.         'An error was occurred.
  986.         '
  987.         'Change a value of the State property
  988.         mvarState = sckError
  989.         'Debug.Print "mvarState = sckError"
  990.         'Close the socket
  991.         Call DestroySocket
  992.         'The OnError event is just for this case
  993.         RaiseEvent OnError(CInt(lngError), GetErrorDescription(lngError), 0, "", "", 0, False)
  994.         'We have nothing to do here anymore
  995.         Exit Sub
  996.         '
  997.     End If
  998.     '
  999.     Select Case lngEventID
  1000.         '
  1001.         Case FD_READ
  1002.             '
  1003.             'Debug.Print "FD_READ"
  1004.             '
  1005.             'Some data has arrived for this socket.
  1006.             'Call the RecvDataToBuffer function that move arrived data
  1007.             'from the Winsock buffer to the local one and returns number
  1008.             'of bytes received.
  1009.             lngBytesReceived = RecvDataToBuffer
  1010.             '
  1011.             'Debug.Print "Bytes received: " & lngBytesReceived
  1012.             '
  1013.             'The BytesReceived property contains number of bytes in
  1014.             'the local buffer of the class.
  1015.             m_lngBytesReceived = m_lngBytesReceived + lngBytesReceived
  1016.             '
  1017.             'The OnDataArrival event is just for the case when some data
  1018.             'was retieved from the Winsock buffer.
  1019.             If lngBytesReceived > 0 Then
  1020.                 RaiseEvent OnDataArrival(Len(m_strRecvBuffer))
  1021.             End If
  1022.             '
  1023.         Case FD_WRITE
  1024.             '
  1025.             'This message means that the socket in a write-able
  1026.             'state, that is, buffer for outgoing data of the transport
  1027.             'service is empty and ready to receive data to send through
  1028.             'the network.
  1029.             '
  1030.             'Debug.Print "FD_WRITE"
  1031.             '
  1032.             'If the local buffer for outgoing data (m_strSendBuffer) is
  1033.             'not empty, the previous call of the send/sendto Winsock API
  1034.             'function was failed. Call the SendBufferedData procedure in
  1035.             'oreder to try to send that data again.
  1036.             If Len(m_strSendBuffer) > 0 Then
  1037.                 '
  1038.                 Call SendBufferedData
  1039.             Else
  1040.                 '
  1041.                 If m_blnSendFlag Then           'Added: 12-SEP-2002
  1042.                     m_blnSendFlag = False       'Added: 12-SEP-2002
  1043.                     RaiseEvent OnSendComplete   'Added: 23-AUG-2002
  1044.                 End If
  1045.                 '
  1046.             End If
  1047.             '
  1048.         Case FD_OOB
  1049.             '
  1050.             'Ignored.
  1051.             '
  1052.         Case FD_ACCEPT
  1053.             '
  1054.             'When the socket is in a listening state, arrival of this message
  1055.             'means that a connection request was received. Call the accept
  1056.             'Winsock API function in oreder to create a new socket for the
  1057.             'requested connection.
  1058.             lngNewSocket = api_accept(m_lngSocketHandle, udtSockAddr, Len(udtSockAddr))
  1059.             '
  1060.             'Debug.Print lngNewSocket & ": created"
  1061.             '
  1062.             'Let the client application know that the request was received
  1063.             'and pass with the event argument a handle of the recently created
  1064.             'socket. The client application should create a new instance of
  1065.             'the CSocket class, and then use the socket handle (lngNewSocket)
  1066.             'to initialize its properties. Another way is to do not create
  1067.             'one more instance of this class. We may close existing socket,
  1068.             'and then accept the new handle:
  1069.             '
  1070.             '  Private Sub objSocket_OnConnectionRequest(ByVal requestID As Long)
  1071.             '      If objSocket.State <> sckClosed Then objSocket.CloseSocket
  1072.             '      objSocket.Accept (requestID)
  1073.             '  End Sub
  1074.             '
  1075.             RaiseEvent OnConnectionRequest(lngNewSocket)
  1076.             '
  1077.         Case FD_CONNECT
  1078.             '
  1079.             'Arrival of this message means that the connection initiated by the call
  1080.             'of the connect Winsock API function was successfully established.
  1081.             '
  1082.             'Get the connection local end-point parameters
  1083.             '
  1084.             lngRetValue = getsockname(m_lngSocketHandle, udtSockAddr, LenB(udtSockAddr))
  1085.             '
  1086.             If lngRetValue = 0 Then
  1087.                 '
  1088.                 'LocalPort property
  1089.                 m_lngLocalPort = IntegerToUnsigned(ntohs(udtSockAddr.sin_port))
  1090.                 'LocalIP property
  1091.                 m_strLocalIP = StringFromPointer(inet_ntoa(udtSockAddr.sin_addr))
  1092.                 'LocalHostName property
  1093.                 lngRetValue = gethostbyaddr(udtSockAddr.sin_addr, 4&, AF_INET)
  1094.                 '---------------------------------------------------------------
  1095.                 'Modified: 31-JUL-2002
  1096.                 '---------------------------------------------------------------
  1097.                 If lngRetValue <> 0 Then
  1098.                     CopyMemory udtHostent, ByVal lngRetValue, Len(udtHostent)
  1099.                     m_strLocalHostName = StringFromPointer(udtHostent.hName)
  1100.                 Else
  1101.                     m_strLocalHostName = m_strLocalIP
  1102.                 End If
  1103.                 '---------------------------------------------------------------
  1104.                 '
  1105.             End If
  1106.             '
  1107.             ' -- Modified: 04-MAR-2002 --
  1108.             '
  1109.             'Change a value of the State property
  1110.             mvarState = sckConnected
  1111.             '
  1112.             'Let the client app know that the connection was established.
  1113.             RaiseEvent OnConnect
  1114.             '
  1115.             ' -- --------------------- --
  1116.             '
  1117.             'Debug.Print "mvarState = sckConnected"
  1118.             '
  1119.         Case FD_CLOSE
  1120.             '
  1121.             'This message means that the remote host is closing the conection
  1122.             '
  1123.             '-------------------------------------------------------------------
  1124.             'Modified: 20-AUG-2002
  1125.             'Thanks to mreggio and other vbip.com Forum members.
  1126.             '-------------------------------------------------------------------
  1127.             Do
  1128.                 '
  1129.                 lngBytesReceived = RecvDataToBuffer
  1130.                 '
  1131.                 If lngBytesReceived > 0 Then
  1132.                     RaiseEvent OnDataArrival(Len(m_strRecvBuffer))
  1133.                 End If
  1134.                 '
  1135.             Loop Until lngBytesReceived = 0 Or lngBytesReceived = SOCKET_ERROR
  1136.             '
  1137.             If mvarState = sckClosing Then
  1138.                 '
  1139.                 '---------------
  1140.                 'Don't even read this as it doesn't work on a very-very
  1141.                 'fast connection, for example: localhost<->localhost :).
  1142.                 'The Do..Loop was moved up, now you can see it above the
  1143.                 '"If mvarState = sckClosing Then" statement
  1144.                 '-----------------
  1145.                 '
  1146.                 'If a value of the State property already is sckClosing,
  1147.                 'the closing of the connection was initiated by the local
  1148.                 'end-point (this socket) of the connection. In other words,
  1149.                 'the shutdown Winsock API function has been called before
  1150.                 '(the FIN segment is already sent by the local end-point).
  1151.                 '
  1152.                 'In this case we need wait until all the data sent by the
  1153.                 'remote end-point of the connection will be received.
  1154.                 '
  1155.                 'Do
  1156.                 '    '
  1157.                 '    lngBytesReceived = RecvDataToBuffer
  1158.                 '    '
  1159.                 '    If lngBytesReceived > 0 Then
  1160.                 '        RaiseEvent OnDataArrival(Len(m_strRecvBuffer))
  1161.                 '    End If
  1162.                 '    '
  1163.                 'Loop Until lngBytesReceived = 0 Or lngBytesReceived = SOCKET_ERROR
  1164.                 '
  1165.             '-------------------------------------------------------------------
  1166.             Else
  1167.                 '
  1168.                 mvarState = sckClosing
  1169.                 'Debug.Print "mvarState = sckClosing"
  1170.                 '
  1171.                 'If a value of the State property is not sckClosing, the
  1172.                 'connectoin is closing by the remote end-point of the
  1173.                 'connection (the FIN segment is sent by the remote host).
  1174.                 'In this case we need send all the remained data from the
  1175.                 'local buffer before to close the socket.
  1176.                 If Len(m_strSendBuffer) > 0 Then
  1177.                     '
  1178.                     Call SendBufferedData
  1179.                     '
  1180.                 End If
  1181.                 '
  1182.             End If
  1183.             '
  1184.             'Close the socket
  1185.             Call DestroySocket
  1186.             '
  1187.             'Change a value of the State property
  1188.             mvarState = sckClosed
  1189.             'Debug.Print "mvarState = sckClosed"
  1190.             '
  1191.             'Let the client app know that the connection is closed
  1192.             RaiseEvent OnClose
  1193.             '
  1194.     End Select
  1195.     '
  1196.     Exit Sub
  1197.     '
  1198. ERROR_HANDLER:
  1199.     '
  1200.     Err.Raise Err.Number, "CSocket.PostSocketEvent", Err.Description    'Modified: 15-APR-2002
  1201.     '
  1202. End Sub
  1203.  
  1204. Friend Sub PostGetHostEvent(ByVal lngRequestID As Long, ByVal lngHostAddress As Long, strHostName As String, Optional lngError As Long)
  1205.     '
  1206.     'This procedure is called by the WindowProc callback function
  1207.     'from the MSocketSupport module. Think about it as about result
  1208.     'returned by the ResolveHost function called from this class.
  1209.     '
  1210.     Dim udtAddress      As sockaddr_in  'socket address - used by the connect Winsock API function
  1211.     Dim lngRetValue     As Long         'value returned by the connect Winsock API function
  1212.     Dim lngPtrToAddress As Long         'pointer to the string that contains IP address - value
  1213.                                         'returned by the inet_ntoa Winsock API function
  1214.     '
  1215.     On Error GoTo ERROR_HANDLER
  1216.     '
  1217.     If lngError > 0 Then
  1218.         '
  1219.         'An error was occerred during resolving the host hame.
  1220.         'For example: "Host not found"
  1221.         '
  1222.         '----------------------------------------------------------------
  1223.         'Added: 28-APR-2002
  1224.         'There is the case when a computer has a valid IP address
  1225.         'but its name cannot be resolved. In this case the code should
  1226.         'countinue the execution - we just don't need to change the
  1227.         'RemoteHost property value.
  1228.         '----------------------------------------------------------------
  1229.         '
  1230.         'Does the strHostName argument contain a valid IP address?
  1231.         lngHostAddress = inet_addr(strHostName)
  1232.         '
  1233.         If lngHostAddress = INADDR_NONE Then    'Added: 28-APR-2002
  1234.             '
  1235.             'Change a value of the State property
  1236.             mvarState = sckError
  1237.             'Debug.Print "mvarState = sckError"
  1238.             '
  1239.             'Let the client app know that an error was occurred.
  1240.             RaiseEvent OnError(CInt(lngError), GetErrorDescription(lngError), 0, "", "", 0, False)
  1241.             '
  1242.             Exit Sub
  1243.             '
  1244.         Else    'Added: 28-APR-2002
  1245.             '
  1246.             'Nothing to do here
  1247.             'Both properties the RemoteHost and RemoteHostIP
  1248.             'have the same value of the IP address string.
  1249.             '
  1250.         End If  'Added: 28-APR-2002
  1251.         '
  1252.     End If
  1253.     '
  1254.     'Check the id value - Do we really need this?
  1255.     If lngRequestID = 0 Then Exit Sub
  1256.     '
  1257.     If lngRequestID = m_lngRequestID Then
  1258.         '
  1259.         'Change a value of the State property
  1260.         mvarState = sckHostResolved
  1261.         'Debug.Print "mvarState = sckHostResolved"
  1262.         '
  1263.         'Initialize the RemoteHost property
  1264.         m_strRemoteHost = strHostName
  1265.         '
  1266.         'Get pointer to the string that contains the IP address
  1267.         lngPtrToAddress = inet_ntoa(lngHostAddress)
  1268.         '
  1269.         'Retrieve that string by the pointer and init the
  1270.         'RemoteHostIP property.
  1271.         m_strRemoteHostIP = StringFromPointer(lngPtrToAddress)
  1272.         '
  1273.         'The ResolveHost function may be called from two methods
  1274.         'of the class: Connect and SendData. The m_varInternalState
  1275.         'variable tells us where the ResolveHost function called
  1276.         'from, and thus what to do here.
  1277.         '
  1278.         If m_varInternalState = istConnecting Then
  1279.             '
  1280.             'The ResolveHost was called from the Connect method, so
  1281.             'we need to continue the process of the connection establishing.
  1282.             '
  1283.             'Build the sockaddr_in structure to pass it to the connect
  1284.             'Winsock API function as an address of the remote host.
  1285.             With udtAddress
  1286.                 '
  1287.                 .sin_addr = lngHostAddress
  1288.                 .sin_family = AF_INET
  1289.                 .sin_port = htons(UnsignedToInteger(CLng(m_lngRemotePort)))
  1290.                 '
  1291.             End With
  1292.             '
  1293.             'Call the connect Winsock API function in order to establish connection.
  1294.             lngRetValue = api_connect(m_lngSocketHandle, udtAddress, Len(udtAddress))
  1295.             '
  1296.             'Since the socket we use is a non-blocking one, the connect Winsock API
  1297.             'function should return a value of SOCKET_ERROR anyway.
  1298.             '
  1299.             If lngRetValue = SOCKET_ERROR Then
  1300.                 '
  1301.                 'The WSAEWOULDBLOCK error is OK for such a socket
  1302.                 '
  1303.                 If Not Err.LastDllError = WSAEWOULDBLOCK Then
  1304.                     'Modified: 31-JUL-2002
  1305.                     RaiseEvent OnError(Err.LastDllError, GetErrorDescription(Err.LastDllError), 0&, "CSocket.PostGetHostEvent", "", 0&, False)
  1306.                 Else
  1307.                     'Change the State property value
  1308.                     mvarState = sckConnecting
  1309.                     'Debug.Print "mvarState = sckConnecting"
  1310.                 End If
  1311.                 '
  1312.             End If
  1313.             '
  1314.         ElseIf m_varInternalState = istSendingDatagram Then
  1315.             '
  1316.             'The ResolveHost was called from the SendData method in
  1317.             'the case when a message-oriented (UDP) socket is used.
  1318.             '
  1319.             Call SendBufferedData
  1320.             '
  1321.         End If
  1322.         '
  1323.     End If
  1324.     '
  1325.     Exit Sub
  1326.     '
  1327. ERROR_HANDLER:
  1328.     '
  1329.     Err.Raise Err.Number, "CSocket.PostGetHostEvent", Err.Description
  1330.     '
  1331. End Sub
  1332.  
  1333. Private Function SocketExists() As Boolean
  1334.     '
  1335.     If m_lngSocketHandle = INVALID_SOCKET Then
  1336.         '
  1337.         'If the m_lngSocketHandle is not a valid value, call
  1338.         'the vbSocket function in order to create a new socket
  1339.         m_lngSocketHandle = vbSocket
  1340.         '
  1341.         If m_lngSocketHandle = SOCKET_ERROR Then
  1342.             '
  1343.             'A value of SOCKET_ERROR means that the socket was not created.
  1344.             'In this case the SocketExists function must return False
  1345.             Exit Function
  1346.             '
  1347.         Else
  1348.             '
  1349.             'Get default size of the Winsock's buffers.
  1350.             Call GetWinsockBuffers  'Modified: 10-MAR-2002
  1351.             '
  1352.         End If
  1353.         '
  1354.     End If
  1355.     '
  1356.     'The m_lngSocketHandle variable contains a valid socket
  1357.     'handle value. In this case the function returns True.
  1358.     SocketExists = True
  1359.     '
  1360. End Function
  1361.  
  1362. Private Sub GetWinsockBuffers()
  1363.     '
  1364.     'This subroutine is to retrieve default size of the Winsock buffers.
  1365.     'These values will be stored in the module level variables:
  1366.     'm_lngSendBufferLen and m_lngRecvBufferLen.
  1367.     'It can be called from the SocketExists and Accept functions.
  1368.     '
  1369.     'Added: 10-MAR-2002
  1370.     '
  1371.     Dim lngRetValue     As Long 'value returned by the getsockopt Winsock API function
  1372.     Dim lngBuffer       As Long 'buffer to pass with the getsockopt call
  1373.     '
  1374.     If mvarProtocol = sckTCPProtocol Then
  1375.         'Buffer for incoming data
  1376.         lngRetValue = getsockopt(m_lngSocketHandle, SOL_SOCKET, SO_RCVBUF, lngBuffer, 4&)
  1377.         m_lngRecvBufferLen = lngBuffer
  1378.         'Buffer for outgoing data
  1379.         lngRetValue = getsockopt(m_lngSocketHandle, SOL_SOCKET, SO_SNDBUF, lngBuffer, 4&)
  1380.         m_lngSendBufferLen = lngBuffer
  1381.     Else
  1382.         'the m_lngMaxMsgSize value is returned by InitWinsockService
  1383.         'function from the MSocketSupport module
  1384.         m_lngSendBufferLen = m_lngMaxMsgSize
  1385.         m_lngRecvBufferLen = m_lngMaxMsgSize
  1386.     End If
  1387.     '
  1388. End Sub
  1389.  
  1390. Private Function RecvDataToBuffer() As Long
  1391.     '
  1392.     'This function is to retrieve data from the Winsock buffer
  1393.     'into the class local buffer. The function returns number
  1394.     'of bytes retrieved (received).
  1395.     '
  1396.     Dim lngBytesReceived        As Long     'value returned by recv/recvfrom Winsock API function
  1397.     Dim lngRetValue             As Long     'value returned by gethostbyaddr Winsock API function
  1398.     Dim strTempBuffer           As String   'just a temporary buffer
  1399.     Dim arrBuffer()             As Byte     'buffer to pass to the recv/recvfrom Winsock API function
  1400.     Dim udtSockAddr             As sockaddr_in 'socket address of the remote peer
  1401.     Dim lngSockAddrLen          As Long     'size of the sockaddr_in structure
  1402.     Dim udtHostent              As HOSTENT  'used to get host name with gethostbyaddr function
  1403.     '
  1404.     'Prepare the buffer to pass it to the recv/recvfrom Winsock API function.
  1405.     'The m_lngRecvBufferLen variable was initialized during creating
  1406.     'of the socket, see the vbSocket function to find out how.
  1407.     ReDim arrBuffer(m_lngRecvBufferLen - 1)
  1408.     '
  1409.     If mvarProtocol = sckTCPProtocol Then
  1410.         '
  1411.         'If the socket is a connection-oriented one, just call the recv function
  1412.         'to retrieve all the arrived data from the Winsock buffer.
  1413.         lngBytesReceived = recv(m_lngSocketHandle, arrBuffer(0), m_lngRecvBufferLen, 0&)
  1414.         '
  1415.     Else
  1416.         '
  1417.         'If the socket uses UDP, it's another story. As stated in the MS Winsock Control
  1418.         'documentation after receiving data the RemoteHost, RemoteHostIP, and RemotePort
  1419.         'properties contains parameters of the machine sending the UDP data. To achive
  1420.         'such a behavior we must use the recvfrom Winsock API function.
  1421.         '
  1422.         lngSockAddrLen = Len(udtSockAddr)
  1423.         '
  1424.         lngBytesReceived = recvfrom(m_lngSocketHandle, arrBuffer(0), m_lngRecvBufferLen, _
  1425.                                     0&, udtSockAddr, lngSockAddrLen)
  1426.         '
  1427.         If Not lngBytesReceived = SOCKET_ERROR Then
  1428.             '
  1429.             'Now the udtSockAddr contains a socket address of the remote host.
  1430.             'Initialize the RemoteHost, RemoteHostIP, and RemotePort properties.
  1431.             '
  1432.             With udtSockAddr
  1433.                 '
  1434.                 'RemotePort property
  1435.                 m_lngRemotePort = IntegerToUnsigned(ntohs(.sin_port))
  1436.                 'RemoteHostIP property
  1437.                 m_strRemoteHostIP = StringFromPointer(inet_ntoa(.sin_addr))
  1438.                 'RemoteHost property
  1439.                 lngRetValue = gethostbyaddr(.sin_addr, 4&, AF_INET)
  1440.                 CopyMemory udtHostent, ByVal lngRetValue, Len(udtHostent)
  1441.                 m_strRemoteHost = StringFromPointer(udtHostent.hName)
  1442.                 '
  1443.             End With
  1444.             '
  1445.         End If
  1446.         '
  1447.     End If
  1448.     '
  1449.     If lngBytesReceived > 0 Then
  1450.         '
  1451.         'Convert a byte array into the VB string
  1452.         strTempBuffer = StrConv(arrBuffer(), vbUnicode)
  1453.         'Store received data in the local buffer for incoming data - m_strRecvBuffer
  1454.         m_strRecvBuffer = m_strRecvBuffer & Left$(strTempBuffer, lngBytesReceived)
  1455.         'Return number of received bytes.
  1456.         RecvDataToBuffer = lngBytesReceived
  1457.         '
  1458.     ElseIf lngBytesReceived = SOCKET_ERROR Then
  1459.         '
  1460.         Err.Raise Err.LastDllError, "CSocket.RecvToBuffer", GetErrorDescription(Err.LastDllError)
  1461.         '
  1462.     End If
  1463.     '
  1464. End Function
  1465.  
  1466. Private Function RecvData(varData As Variant, blnPeek As Boolean, Optional varType As Variant, Optional maxLen As Variant) As Long
  1467.     '
  1468.     'This function is to retrieve data from the local buffer (m_strRecvBuffer).
  1469.     'It can be called by two public methods of the class - GetData and PeekData.
  1470.     'Behavior of the function is defined by the blnPeek argument. If a value of
  1471.     'that argument is True, the function returns number of bytes in the
  1472.     'local buffer, and copy data from that buffer into the varData argument.
  1473.     'If a value of the blnPeek is False, then this function returns number of
  1474.     'bytes received, and move data from the local buffer into the varData
  1475.     'argument. MOVE means that data will be removed from the local buffer.
  1476.     '
  1477.     Dim strRecvData As String   'temporary string buffer
  1478.     Dim arrBuffer() As Byte     'temporary byte array buffer
  1479.     '
  1480.     'If the local buffer is empty, go away - we have nothing to do here.
  1481.     If Len(m_strRecvBuffer) = 0 Then Exit Function
  1482.     '
  1483.     If IsEmpty(maxLen) Then
  1484.         maxLen = 0
  1485.     End If
  1486.     '
  1487.     If (Not maxLen > Len(m_strRecvBuffer)) And (maxLen > 0) Then
  1488.         '
  1489.         strRecvData = Left$(m_strRecvBuffer, CLng(maxLen))
  1490.         '
  1491.         If Not blnPeek Then
  1492.             m_strRecvBuffer = Mid$(m_strRecvBuffer, CLng(maxLen + 1))
  1493.         End If
  1494.         '
  1495.         arrBuffer() = StrConv(strRecvData, vbFromUnicode)
  1496.         '
  1497.     Else
  1498.         '
  1499.         arrBuffer() = StrConv(m_strRecvBuffer, vbFromUnicode)
  1500.         '
  1501.         If Not blnPeek Then
  1502.             m_strRecvBuffer = ""
  1503.         End If
  1504.         '
  1505.     End If
  1506.     '
  1507.     If IsEmpty(varType) Then
  1508.         varData = CStr(StrConv(arrBuffer(), vbUnicode))
  1509.     Else
  1510.         '
  1511.         Select Case varType
  1512.             Case vbArray + vbByte
  1513.                 'ModifiedgPtrot    OkstAddress
  1514.         
  1515.             Case vbArray + vbt    
  1516.   a the blnPeek is False, then this function rerot    Ok 
  1517.     'that ay + W A
  1518.   lse, then thNE)
  1519.        tlse, then this fun vbArra       '
  1520.         'Does the strHostName argument contain a valid IP address?
  1521. )ndse Err-2002
  1522.  4es the strHo, vbFromUnicode)
  1523. g theIP address?bPeek is Falp_in structurec?bPeek is Falp_iA5o
  1524.      adressHo, vbFromUnse, then this functioromUni'local bB    l continue tE  'Added: 12-SEP-2i' Err.Raise Err.Number, "CSocket.Pos> SOCKET_ERROR Then
  1525.         '
  1526.         If llError)
  1527.                     Then
  1528.         = hrs the
  1529.     oming data - m_strRecein Exit FunctioBuffer(0), m_lngRecvBufferLentv,ontiWf llErroFunctiodata - m_strRecein Exit Functioe))
  1530.     ElAd_e   tlse, then this will be remUCtrHo, vbFromnnect method, so
  1531.  Err.Raise Err.e remUC:tiohtfer.
  1532.   ia.hName)
  1533.             '
  1534.         stG hrs'  ElAd_e   tlse,r(udtHosLrs      As Lorr,      m_lngRemotePort = InsataF_INETe&n_ad arrBufe&n_ad arrBufe&n_ad was initiaName argVE means tha----
  1535.     lse
  1536.    --
  1537.     lse
  1538.     , AF_INET)iferW the
  1539.     oming data - m_strRecein Exa - m_strRece caht
  1540.     '
  1541. irTempBuffer = StrCA))
  1542.     Else locPrint "mvarStckAddr.sin_addr))))))))tnr))))))))tnrAddr.sin_Raise Ere   tlseN contain remU)tnrAddr.sin_Raise Ere   tlseata - m_strRecein Exa - m_strRece caht
  1543. _ER     lue ceived
  1544.           hCall the accept
  1545.   CStr(StrConv(arrBuffeblic ProaxLniseata - m_st  If m_lnD End
  1546.             CaseoySocket
  1547.  Len +l              'c   xLniselceivedhe Resobe received.
  1548.  e receivet End If
  1549.  'l"l(ocket
  1550.  Len +l     ResobmpBuffd from n tose
  1551.   tG h3 remU)tnrlocal bufrRecvDatsVeTrue, a)))_lngRecvBunstrRethod> Theeceived.
  1552.  e receivetrRethod> Theeceived.
  1553.  eived =e    m    m    m    m       blic ProaxLniseBo  'Added: 1End If
  1554.  O(m_strroperty
  1555.     > Theeceived.
  1556.  e rece'l"l(ty
  1557.     > T
  1558.                 '        RaiseEvent OoInt  > T
  1559.    lAd_e   tlse,k API function.
  1560.       ss?
  1561. )ndse Err-200value of tmpBuf.L  Re
  1562.        Oeceived.
  1563.  e receivet End If
  1564.  'l"l(ocket
  1565.  Len +l     ResobmpBuffd from n r= INA
  1566.    ahen t,:ceived.
  1567.  e.Prl"l(ocket
  1568.  LhRe
  1569.        Oecei   End If
  1570.     'aisT
  1571.         ts = True
  1572.     '
  1573. erred dvarT-----
  1574.                 'Modified: 31-JUL-2002
  1575. (m_strRecvBuffer, CLng(maxLen te Function ruta ase
  1576.                      ts = T"ither way  ufer.e
  1577.     , AF_INEr.e
  1578.     , AF_INEr.eCnFunctR, Optr.e
  1579.     , r CodataSub
  1580.     '
  1581. ckAddrOCKtDR, Optells uD End
  1582.            dduffer(0T'
  1583.        
  1584.     , r CodasuD Eed data in thettttttttttttttttttion = "Returns///////////////////////////////////D r CfromLTtlse,    Dioes the strHostNamuD End
  1585. -
  1586.  O: 31-JU///PO////////////D r Cly =      he local buffarStckAddr.siseEvtr.sisaSub
  1587.     '
  1588.  O: 31-JU//m    m   lue ceive 'Ad=Sub
  1589.    ) End
  1590. -
  1591.  O:re host./////////D r Cly =   bm   e process of 7ionne   nm   e processtlue oJhoutHandle, SOL_SOCKET, SO_BROADCAST, 0&, 4&)
  1592. (m_sttttttttttttttttn
  1593.     , ata Ihh f 7ioellsRemoto   dduffer(0ers()
  1594.   > Tr Cly =  sisaSub
  1595.     '
  1596.  O: 31-JU//m    m  dduffer(0ers()
  1597.   > Tr Cly =  sisaSub
  1598.     'ss of 7ion     aroa '
  1599.     'If thwsnm   e processtlue ollSub
  1600.    duffer(0e'Change a    In     aroRyed in t)IplngRetValuer.s be s(
  1601.   mvar 'v0ers()
  1602.   > Trto   dduffertc
  1603.         Selected)
  1604. gRe"ither way  ar 'v0ers()
  1605. Of thwrs()
  1606.  f9=  sisaSub'Added: 1En fromAddr, lngSocHost9=  sisaSubetttttttttn
  1607. ()
  1608. Of thwrsp  s
  1609.                 Else
  1610.       Pmnect e
  1611.      hett----
  1612.                 'MsisaSubetttttttttn
  1613. ()
  1614. Of thwrs'MsisaSubeEnd Function
  1615.  
  1616. Private    OkstAdd Selectedd FuniBuffd from n tose
  1617.   ters()e As String, 't = InsataF_INETwas r    Err.RAn
  1618. ()
  1619. Of thwrs= C    'rece.Number, "CSocketV CaseoySocketkDatars the
  1620.     oming data - m_strRecein   '
  1621.     'Thi= Iument unD EnduniBuffd'onne       'Thi=   Dim sdempB     'sin_ 1En   'sukef
  1622.   a   'sukef
  1623.   g.--
  1624.  r
  1625.  
  1626. Private Function Sockes////dse Err-200value ofu   Dioea's anothr
  1627.  
  1628. Privates      local machine namen(Err.Lkhould cr.Description
  1629.     '
  1630. rocass with the event arcevent arcevent arcevent arce's a,r'
  1631.  O: 31-JU//m    m   lue cetkDatars the
  1632.     oming data - m_strRecein   'f
  1633.     'that argse Err.Number, "CSerBuffer(.&eCSerBuffer(.&eCSerBuffer(.&eCSerBs theGr
  1634.    ">ruta ase
  1635. oalled by te = INVALID_SOCtConnecting Then
  1636.             '
  1637.             'The ResolveHost     '    'not empEol ThenCSerta = -
  1638.        theGr
  1639.    vcesstlue oJhoutyever'seHos   Dhoutyever' Sew of bVALID_Sr///////D r hat arkduring creating
  1640.     'of the socket, see the vbSodEol Thetwsnmcess 'of  'Don't evFV
  1641.    tlue oll S_nd02
  1642. (m_strR,.pElAd_e   )TSub
  1643.     'mpEol ThenCSerta = -
  1644.       oiN.->y
  1645.     ominis to re  oiN.->y
  1646.   b
  1647.     'mpEol Ou.g creating
  1648.     'ofng
  1649.     'ofngcnt    '.> what to do here.
  1650. d from two methods
  1651.         'of the 'of the class: Cok S_ner, vbFromU----      '  'of ockaddr_in 'socked cr.DetttttttgGr, vbFrocGlSub
  1652. (m_strRecvBuffWs
  1653.        re.tttgGr, vbFrocGiable wutnExaEvbFromU----      'l02 m_vagrPeek Then
  1654. oWsTIufrRecvDatsVeThenCSerta = -
  1655.      c  'Adde
  1656.  rar.s be s(re
  1657.         'RemoteHosrs()nsock API fu           'tnExaEvbrRecvBuffWs
  1658.     'mpEAlt propsRecv'Adde
  1659.  rar.soteHo
  1660.        Oecei m   e proces     a   I fueHo
  1661.     Else
  1662.  m_va    'c  Eleans that_ei m   e proRecvR m   e prostn        ebontain remU)tnrAddrHo
  1663.  heno'eetBytesReceived =, "", 0&, FrAddrHo
  1664.  ostAdA         'eetBy
  1665.   tain re.
  1666.     'TheWinsock Control
  1667.    mS0   Oe  tain re.
  1668.   Oe )_va Uvm n toseE      'eetBy
  1669.  e'unBe proRecvR m   e prostn        ebontain remU)tnrAddrHo
  1670.              ts = T"ither way  ufer.e
  1671.     , AF_INEr.e
  1672.     , Ahe R proces     a   I fGue = gethostbyaddr(ud proRecvR m      'rece.Number,    Etn        eba         'ee cet vbBD  'so tss'value returned   'that a,'n       nobmpBuffd from nat to dduffer(TTotfEecvR m      'recconeecep             ebonr
  1673.           '
  1674.      '
  1675.      '
  1676.   sL fromcevent arce's a,YmpBuffd from nat to dostn        t Oom nat 'hetwsnms'value returned e returnewRecvecvR m   e prostnThen
  1677. 4rnewReca.ptopsRecv connection 'hetwsnms'v     a Number, "Cen g       motwRecagError)=cch t4 to do here.
  1678. d fris will be         tlue oll S_nd02
  1679. (mC   'varHo
  1680. RecvBuffer = m_s's aaoll S_ndr, hGvbFro remU)tnr-be         tlue oll S_nd02
  1681. (mC   'varHocvBuffer/oll S,oll S_nd02
  1682. (mC   'fers()mCnt is a. nG State propai> + vbt  0dled fris will beeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeNSs           ser/oll SiscvD*his sSiDs sSiDs sSiDs I   
  1683.    und02- tlu    , g here.
  1684. d frifert
  1685.     '
  1686. iLmU)tnr-be         tloll Sis vbt     'e'mpEol ThenCSerta =rere. ThenCSerta =rereven       '
  1687.  
  1688.     , AF_INis will be        i- tlu    =rere.SiDs pro     Pmnect e
  1689.      hett----
  1690.               k(m_strRecvBM        k(m_strRecvonr
  1691.           k(m_sa. ThenCSerBM   e     k(m_-nstrRecvonr
  1692.       'ThenCSerBM   e     k(m_-nstrRecvonr
  1693.   VeThenCSerHedure is car(0), m_lngRecvBufferLentv      k(m_strRecvonrsa.no+l Received)
  1694.         'Return number of received b
  1695.           k(m_sa. ThenCSerBM   e     k(m_-nstrRecvoferLentv      k(mdtSockAddr))
  1696.    emofhe acceAe
  1697.             '
  1698.    02- tlu    , g EmC   'varHoy
  1699.  e'nore.
  1700.   O  , g)nbi 'document(nM   I=0Poe
  1701.        ecvBuffer
  1702.  a ase
  1703.                ,    Etn        eba         'ee cet vbBD  'so tss'valn.o dostm_strRee
  1704.        ec   I fueHo
  1705.     Elsecveeeeeeeeeeee g)nbi sSiD
  1706.        ec   I fNee d   '  'of ockaddgrarceD
  1707.        ec   I fNeerw ofeAe
  1708.             '
  1709.    02- tlu    , g EmC   'string.
  1710.      , g)nbi 'document(nM   I=0Poe
  1711.           '
  1712.   tlu s Falp_Cen gr to w Falp_Cen TExaEvbFromU.'Don't)Eol      a   I fGustrHo ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '