{"id":219,"date":"2009-07-10T22:05:39","date_gmt":"2009-07-11T01:05:39","guid":{"rendered":"http:\/\/leandroascierto.com\/blog\/?p=219"},"modified":"2011-08-27T21:20:46","modified_gmt":"2011-08-28T00:20:46","slug":"winsock32","status":"publish","type":"post","link":"https:\/\/leandroascierto.com\/blog\/winsock32\/","title":{"rendered":"WinSock32"},"content":{"rendered":"<p>Este es un m\u00f3dulo para trabajar con los Socket de Windows, vendr\u00eda a ser un reemplazo del WinSock.ocx, en este me he basado en el m\u00f3dulo de\u00a0<a href=\"mailto:KPDTeam@AllAPI.net\">KPD-Team<\/a>\u00a0y lo reform\u00e9 a mi gusto. Su uso creo, es muy sencillo y pr\u00e1ctico, especialmente a la hora de trabajar con m\u00faltiples conexiones, si lo utilizan tal vez puedan encontrarse con algunas diferencias con respecto a la forma convencional de trabajo de como se utiliza con el WinSock.ocx.<br \/>\nA continuaci\u00f3n voy a dejar dos ejemplos de uso, en el cual expliqu\u00e9 detalladamente, para su f\u00e1cil entendimiento:<br \/>\nEl primero trata de una conexi\u00f3n Cliente-Servidor de tipo Chat donde el Servidor puede escuchar en distintos puertos a la vez y aceptar varias conexiones al mismo tiempo, para la parte Cliente tambi\u00e9n puede realizar m\u00e1s de una conexi\u00f3n y en diferentes puertos a la vez.<br \/>\nEl segundo se trata de una conexi\u00f3n Cliente-Servidor para Transferir Archivos.<br \/>\nUna cosa para resaltar, si es que lo van a usar, es que deben agregar manualmente las subrutinas comentadas en el final del m\u00f3dulo al formulario o m\u00f3dulo clase que llame a la funci\u00f3n\u00a0<em>InitWinSock Me<\/em>\u00a0 del m\u00f3dulo WinSock32.<br \/>\nNo lo he probado a full, pero creo que est\u00e1 funcionando perfectamente, cualquier inquietud, sugerencia o error pueden utilizar el sistema de comentarios.<\/p>\n<pre class=\"brush: vb; title: ; notranslate\" title=\"\">\r\nOption Explicit\r\n\r\n' --------------------------------------------------------------------\r\n' Autor:     Leandro Ascierto\r\n' WEB:       www.leandroascierto.com.ar\r\n' Fecha:     09\/07\/2009\r\n' Adaptado a mi gusto :)\r\n' Basado en el m\u00f3dulo de KPD-Team  http:\/\/www.allapi.net\/\r\n'----------------------------------------------------------------------\r\n\r\nPrivate Declare Function accept Lib &quot;wsock32.dll&quot; (ByVal s As Long, addr As SOCKADDR, addrlen As Long) As Long\r\nPrivate Declare Function bind Lib &quot;wsock32.dll&quot; (ByVal s As Long, addr As SOCKADDR, ByVal namelen As Long) As Long\r\nPrivate Declare Function closesocket Lib &quot;wsock32.dll&quot; (ByVal s As Long) As Long\r\nPrivate Declare Function Connect Lib &quot;wsock32.dll&quot; Alias &quot;connect&quot; (ByVal s As Long, addr As SOCKADDR, ByVal namelen As Long) As Long\r\nPrivate Declare Function htonl Lib &quot;wsock32.dll&quot; (ByVal hostlong As Long) As Long\r\nPrivate Declare Function htons Lib &quot;wsock32.dll&quot; (ByVal hostshort As Long) As Integer\r\nPrivate Declare Function inet_ntoa Lib &quot;wsock32.dll&quot; (ByVal inn As Long) As Long\r\nPrivate Declare Function Listen Lib &quot;wsock32.dll&quot; Alias &quot;listen&quot; (ByVal s As Long, ByVal backlog As Long) As Long\r\nPrivate Declare Function recv Lib &quot;wsock32.dll&quot; (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal Flags As Long) As Long\r\nPrivate Declare Function Send Lib &quot;wsock32.dll&quot; Alias &quot;send&quot; (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal Flags As Long) As Long\r\nPrivate Declare Function Socket Lib &quot;wsock32.dll&quot; Alias &quot;socket&quot; (ByVal af As Long, ByVal s_type As Long, ByVal protocol As Long) As Long\r\nPrivate Declare Function gethostbyname Lib &quot;wsock32.dll&quot; (ByVal host_name As String) As Long\r\nPrivate Declare Function gethostname Lib &quot;wsock32.dll&quot; (ByVal host_name As String, ByVal namelen As Long) As Long\r\nPrivate Declare Function WSAStartup Lib &quot;wsock32.dll&quot; (ByVal wVR As Long, lpWSAD As WSADataType) As Long\r\nPrivate Declare Function WSACleanup Lib &quot;wsock32.dll&quot; () As Long\r\nPrivate Declare Function WSAIsBlocking Lib &quot;wsock32.dll&quot; () As Long\r\nPrivate Declare Function WSACancelBlockingCall Lib &quot;wsock32.dll&quot; () As Long\r\nPrivate Declare Function inet_addr Lib &quot;wsock32.dll&quot; (ByVal cp As String) As Long\r\nPrivate Declare Function WSAAsyncSelect Lib &quot;wsock32.dll&quot; (ByVal s As Long, ByVal hWnd As Long, ByVal wMsg As Long, ByVal lEvent As Long) As Long\r\nPrivate Declare Function SetWindowLong Lib &quot;user32&quot; Alias &quot;SetWindowLongA&quot; (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long\r\nPrivate Declare Function CallWindowProc Lib &quot;user32&quot; Alias &quot;CallWindowProcA&quot; (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long\r\nPrivate Declare Function CreateWindowEx Lib &quot;user32&quot; Alias &quot;CreateWindowExA&quot; (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long\r\nPrivate Declare Function DestroyWindow Lib &quot;user32.dll&quot; (ByVal hWnd As Long) As Long\r\nPrivate Declare Function lstrlen Lib &quot;kernel32&quot; Alias &quot;lstrlenA&quot; (ByVal lpString As Any) As Long\r\nPrivate Declare Function GetTickCount Lib &quot;kernel32.dll&quot; () As Long\r\nPrivate Declare Sub CopyMemoryIP Lib &quot;kernel32&quot; Alias &quot;RtlMoveMemory&quot; (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)\r\nPrivate Declare Sub MemCopy Lib &quot;kernel32&quot; Alias &quot;RtlMoveMemory&quot; (Dest As Any, Src As Any, ByVal cb As Long)\r\nPrivate Declare Sub Sleep Lib &quot;kernel32.dll&quot; (ByVal dwMilliseconds As Long)\r\n\r\nPrivate Type WSADataType\r\n    wVersion As Integer\r\n    wHighVersion As Integer\r\n    szDescription As String * 257\r\n    szSystemStatus As String * 129\r\n    iMaxSockets As Integer\r\n    iMaxUdpDg As Integer\r\n    lpVendorInfo As Long\r\nEnd Type\r\n\r\nPrivate Type HostEnt\r\n    hName As Long\r\n    hAliases As Long\r\n    hAddrType As Integer\r\n    hLen As Integer\r\n    hAddrList As Long\r\nEnd Type\r\n\r\nPrivate Type SOCKADDR\r\n    sin_family As Integer\r\n    sin_port As Integer\r\n    sin_addr As Long\r\n    sin_zero As String * 8\r\nEnd Type\r\n\r\nPrivate Const WINSOCK_MESSAGE As Long = 1025\r\nPrivate Const INADDR_NONE As Long = &amp;HFFFF\r\nPrivate Const INADDR_ANY As Long = &amp;H0\r\nPrivate Const IPPROTO_TCP As Long = 6\r\nPrivate Const INVALID_SOCKET As Long = -1\r\nPrivate Const SOCKET_ERROR As Long = -1\r\nPrivate Const SOCK_STREAM As Long = 1\r\nPrivate Const AF_INET As Long = 2\r\nPrivate Const PF_INET As Long = 2\r\nPrivate Const FD_READ As Long = &amp;H1&amp;\r\nPrivate Const FD_WRITE As Long = &amp;H2&amp;\r\nPrivate Const FD_OOB As Long = &amp;H4&amp;\r\nPrivate Const FD_ACCEPT As Long = &amp;H8&amp;\r\nPrivate Const FD_CONNECT As Long = &amp;H10&amp;\r\nPrivate Const FD_CLOSE As Long = &amp;H20&amp;\r\nPrivate Const GWL_WNDPROC As Long = (-4)\r\n\r\nPrivate PrevProc As Long\r\nPrivate bIsInit As Boolean\r\nPrivate hWin As Long\r\nPrivate m_ObjectHost As Object\r\nPrivate TimeOut As Long\r\n\r\nPublic PortOpen  As Collection       ' Colecci\u00f3n de los puertos abiertos, tiene como key el ID\/Sesi\u00f3n de los puertos Abiertos.\r\nPublic PortSesion As Collection      ' Colecci\u00f3n de los ID\/Sesi\u00f3n de los puertos Abiertos.\r\n\r\nPublic Sockets As Collection         ' Colecci\u00f3n de el ID\/Sesi\u00f3n de las Conexiones establecidas.\r\nPublic IPAddresses As Collection     ' Colecci\u00f3n de las IP de las Conexiones establecidas, tiene como key el ID\/Sesi\u00f3n.\r\nPublic PortConection As Collection   ' Colecci\u00f3n de los Puertos de las Conexiones establecidas, tiene como key el ID\/Sesi\u00f3n.\r\n\r\nPublic CurrentSocketHandle As Long   ' ID de la \u00faltima sesi\u00f3n activa.\r\n\r\n' Esta funci\u00f3n inicializa los Socket, debe hallarse al comienzo, y ObjectHost es el formulario o m\u00f3dulo clase que recibir\u00e1 los Eventos\/Mensajes\r\n' En ese formulario o m\u00f3dulo clase deber\u00e1n ir las l\u00edneas comentadas que se encuentran al final de este m\u00f3dulo.\r\n\r\nPublic Function InitWinSock(ObjectHost As Object) As Boolean\r\n    Dim StartupData As WSADataType\r\n    Set Sockets = New Collection\r\n    Set IPAddresses = New Collection\r\n    Set PortOpen = New Collection\r\n    Set PortSesion = New Collection\r\n    Set PortConection = New Collection\r\n\r\n    Set m_ObjectHost = ObjectHost\r\n\r\n    If Not bIsInit Then\r\n        If Not WSAStartup(&amp;H101, StartupData) Then\r\n            bIsInit = True\r\n            hWin = CreateWindowEx(0&amp;, &quot;STATIC&quot;, &quot;SOCKET_WINDOW&quot;, 0&amp;, 0&amp;, 0&amp;, 0&amp;, 0&amp;, 0&amp;, 0&amp;, App.hInstance, ByVal 0&amp;)\r\n            PrevProc = SetWindowLong(hWin, GWL_WNDPROC, AddressOf WindowProc)\r\n        Else\r\n            bIsInit = False\r\n        End If\r\n    End If\r\n\r\n    InitWinSock = bIsInit\r\n\r\nEnd Function\r\n\r\n' Esta funci\u00f3n es importante llamarla cuando se descarga el formulario, nunca cerrar el Visual Basic desde el Stop\r\n' Sino no se ejecutara esta rutina, el IDE de Visual Basic se cerrar\u00e1 autom\u00e1ticamente dando lugar a no guardar los cambios.\r\n\r\nPublic Sub TerminateWinSock()\r\n\r\n    Dim Ret As Long\r\n    Dim Cnt As Long\r\n\r\n    For Cnt = 1 To Sockets.Count\r\n        WsClose Sockets.Item(1)\r\n    Next\r\n\r\n    For Cnt = 1 To PortSesion.Count\r\n        closesocket PortSesion.Item(1)\r\n        PortSesion.Remove (1)\r\n        PortOpen.Remove (1)\r\n    Next\r\n\r\n    If WSAIsBlocking Then WSACancelBlockingCall\r\n\r\n    Call WSACleanup\r\n\r\n    bIsInit = False\r\n    SetWindowLong hWin, GWL_WNDPROC, PrevProc\r\n    DestroyWindow hWin\r\n\r\n    Set Sockets = Nothing\r\n    Set IPAddresses = Nothing\r\n    Set PortConection = Nothing\r\n    Set PortSesion = Nothing\r\n    Set PortOpen = Nothing\r\n\r\nEnd Sub\r\n\r\n' Funci\u00f3n para conectar, Host es la ip o el dsn a que se quiera conectar, y port el puerto.\r\n' Si conecta la funci\u00f3n retorna el ID de la sesi\u00f3n del Socket, de lo contrario 0.\r\n\r\nPublic Function WsConnect(ByVal Host As String, ByVal Port As Long) As Long\r\n\r\n    Dim s As Long\r\n    Dim Sockin As SOCKADDR\r\n\r\n    Sockin.sin_family = AF_INET\r\n    Sockin.sin_port = htons(Port)\r\n\r\n    If Sockin.sin_port = INVALID_SOCKET Then Exit Function\r\n\r\n    Sockin.sin_addr = GetHostByNameAlias(Host$)\r\n\r\n    If Sockin.sin_addr = INADDR_NONE Then Exit Function\r\n\r\n    s = Socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)\r\n    If s &lt; 0 Then Exit Function\r\n\r\n    If Connect(s, Sockin, 16) &lt;&gt; 0 Then\r\n        If s Then closesocket s\r\n        Exit Function\r\n    End If\r\n\r\n    If WSAAsyncSelect(s, hWin, ByVal WINSOCK_MESSAGE, ByVal FD_READ Or FD_WRITE Or FD_CONNECT Or FD_CLOSE) Then\r\n        closesocket s\r\n    Else\r\n        IPAddresses.Add GetAscIp(Sockin.sin_addr), CStr(s)\r\n        Sockets.Add s, CStr(s)\r\n        PortConection.Add Port, CStr(s)\r\n        CurrentSocketHandle = s\r\n        WsConnect = s\r\n    End If\r\n\r\nEnd Function\r\n\r\n' Funci\u00f3n para poner a la escucha en determinado puerto.\r\n' Si no ocurre ning\u00fan error y el puerto est\u00e1 disponible, la funci\u00f3n retorna el ID de la sesi\u00f3n del Socket, de lo contrario 0.\r\n\r\nPublic Function WsListenInPort(ByVal Port As Long) As Long\r\n\r\n    Dim s As Long\r\n    Dim Sockin As SOCKADDR\r\n\r\n    Sockin.sin_family = AF_INET\r\n    Sockin.sin_port = htons(Port)\r\n\r\n    If Sockin.sin_port = INVALID_SOCKET Then Exit Function\r\n\r\n    Sockin.sin_addr = htonl(INADDR_ANY)\r\n\r\n    If Sockin.sin_addr = INADDR_NONE Then Exit Function\r\n\r\n    s = Socket(PF_INET, SOCK_STREAM, 0)\r\n    If s &lt; 0 Then Exit Function     If bind(s, Sockin, 16) Then         closesocket s         Exit Function     End If     If WSAAsyncSelect(s, hWin, ByVal WINSOCK_MESSAGE, ByVal FD_READ Or FD_WRITE Or FD_CLOSE Or FD_ACCEPT) Then         closesocket s         Exit Function     End If     If Listen(s, 1) Then         closesocket s     Else         WsListenInPort = s         PortOpen.Add Port, CStr(s)         PortSesion.Add s, CStr(s)     End If End Function ' Esta funci\u00f3n Cierra un puerto previamente abierto, si se afirma ForceCloseConection, cerrar\u00e1 todas las conexiones establecidas en ese puerto ' de lo contrario, las conexiones que ya estaban establecidas permanecen y pueden seguir enviando mensajes, pero no se podr\u00e1 hacer una nueva conexi\u00f3n a ese puerto ' si todo sale bien la funcion retorna True. Public Function WsClosePort(ByVal Port As Long, Optional ForceCloseConection As Boolean) As Boolean     On Error GoTo ErrOut     Dim s As Long     Dim Cnt As Long     For Cnt = 1 To PortOpen.Count         If PortOpen(Cnt) = Port Then             s = PortSesion(Cnt)             Exit For         End If     Next     If s = 0 Then Exit Function     closesocket s     PortSesion.Remove CStr(s)     PortOpen.Remove CStr(s)     If ForceCloseConection Then         For Cnt = Sockets.Count To 1 Step -1             If PortConection(Cnt) = Port Then                 WsClose Sockets(Cnt)             End If         Next     End If     WsClosePort = True     Exit Function ErrOut:     WsClosePort = False End Function ' Esta funci\u00f3n env\u00eda datos al servidor, el primer par\u00e1metro es el ID de la sesi\u00f3n, la cual la podemos obtener de Sockets(index) ' o con CurrentSocketHandle que es el \u00faltimo ID de sesi\u00f3n activa. ' El segundo par\u00e1metro la data a enviar. ' Si el mensaje se envi\u00f3 con \u00e9xito la funci\u00f3n devuelve True Public Function SendData(Socket As Long, Data As Variant) As Boolean     Dim Ret As Long     Dim TheMsg() As Byte, sTemp$     TheMsg = &quot;&quot;     Select Case VarType(Data)         Case 8209   'byte array             sTemp = Data             TheMsg = sTemp         Case 8      'String             sTemp = StrConv(Data, vbFromUnicode)         Case Else             sTemp = CStr(Data)             sTemp = StrConv(Data, vbFromUnicode)     End Select     TheMsg = sTemp     If UBound(TheMsg) &gt; -1 Then\r\n        Ret = Send(Socket, TheMsg(0), (UBound(TheMsg) - LBound(TheMsg) + 1), 0)\r\n\r\n        If Ret = SOCKET_ERROR Then\r\n            TimeOut = GetTickCount + 5000\r\n            Do While Ret = SOCKET_ERROR\r\n                Ret = Send(Socket, TheMsg(0), (UBound(TheMsg) - LBound(TheMsg) + 1), 0)\r\n                DoEvents\r\n                Sleep 10\r\n                If TimeOut &lt; GetTickCount Then Exit Do\r\n            Loop\r\n        End If\r\n        SendData = Ret &lt;&gt; SOCKET_ERROR\r\n    End If\r\n\r\nEnd Function\r\n\r\n' Esta funci\u00f3n cierra la conexi\u00f3n indicada mediante el ID de sesi\u00f3n que se pase como par\u00e1metro\r\n' el ID lo obtenemos de Sockets(index) o con CurrentSocketHandle que es el \u00faltimo ID de sesi\u00f3n activa.\r\n' si todo sale bien la funci\u00f3n retorna True.\r\n\r\nPublic Function WsClose(ByVal s As Long) As Boolean\r\nOn Local Error Resume Next\r\n    WsClose = closesocket(s)\r\n    IPAddresses.Remove CStr(s)\r\n    Sockets.Remove CStr(s)\r\n    PortConection.Remove CStr(s)\r\nEnd Function\r\n\r\n' Funci\u00f3n que retorna la IP Local.\r\nPublic Function GetLocalIp() As String\r\n\r\n    Dim sHostName As String * 256\r\n    Dim lpHost As Long\r\n    Dim Host As HostEnt\r\n    Dim dwIPAddr As Long\r\n    Dim tmpIPAddr() As Byte\r\n    Dim i As Integer\r\n    Dim sIPAddr As String\r\n\r\n    lpHost = gethostbyname(sHostName)\r\n\r\n    CopyMemoryIP Host, lpHost, Len(Host)\r\n    CopyMemoryIP dwIPAddr, Host.hAddrList, 4\r\n    ReDim tmpIPAddr(1 To Host.hLen)\r\n    CopyMemoryIP tmpIPAddr(1), dwIPAddr, Host.hLen\r\n    For i = 1 To Host.hLen\r\n        sIPAddr = sIPAddr &amp; tmpIPAddr(i) &amp; &quot;.&quot;\r\n    Next\r\n    GetLocalIp = Mid$(sIPAddr, 1, Len(sIPAddr) - 1)\r\n\r\nEnd Function\r\n\r\n' Funci\u00f3n que retorna el Nombre de Host Local.\r\n\r\nPublic Function LocalHostName() As String\r\n    Dim sHostName As String * 256\r\n    If gethostname(sHostName, 256) &lt;&gt; INVALID_SOCKET Then\r\n        LocalHostName = Trim$(sHostName)\r\n    End If\r\nEnd Function\r\n\r\n' Funci\u00f3n Privada del m\u00f3dulo.\r\nPrivate Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long\r\n\r\nOn Local Error Resume Next\r\n\r\n    If uMsg = WINSOCK_MESSAGE Then\r\n\r\n        Dim mIP As String\r\n        Dim mPuerto As String\r\n\r\n        CurrentSocketHandle = wParam\r\n\r\n        Select Case lParam\r\n\r\n            Case FD_ACCEPT\r\n                Dim s As Long, tempAddr As SOCKADDR\r\n                s = accept(wParam, tempAddr, Len(tempAddr))\r\n\r\n                mIP = GetAscIp(tempAddr.sin_addr)\r\n                mPuerto = PortOpen(CStr(wParam))\r\n\r\n                IPAddresses.Add mIP, CStr(s)\r\n                Sockets.Add s, CStr(s)\r\n                PortConection.Add mPuerto, CStr(s)\r\n\r\n                Call m_ObjectHost.Socket_Conect(s, mIP, mPuerto)\r\n\r\n            Case FD_CONNECT\r\n                'Debug.Print &quot;FD_CONNECT&quot;\r\n\r\n            Case FD_WRITE\r\n                'Debug.Print &quot;FD_WRITE&quot;\r\n\r\n            Case FD_READ\r\n                Dim sTemp As String, lRet As Long, szBuf As String\r\n\r\n                Do\r\n                    szBuf = String(1024, 0)\r\n                    lRet = recv(wParam, ByVal szBuf, Len(szBuf), 0)\r\n                    If lRet &gt; 0 Then sTemp = sTemp + Left$(szBuf, lRet)\r\n                Loop Until lRet  0 Then\r\n                    mIP = IPAddresses(CStr(wParam))\r\n                    mPuerto = PortConection(CStr(wParam))\r\n                    Call m_ObjectHost.Socket_DataArrival(wParam, mIP, mPuerto, sTemp)\r\n                End If\r\n\r\n            Case Else 'FD_CLOSE\r\n                mPuerto = PortConection(CStr(wParam))\r\n                mIP = IPAddresses(CStr(wParam))\r\n                WsClose wParam\r\n                Call m_ObjectHost.Socket_Close(wParam, mIP, mPuerto)\r\n\r\n        End Select\r\n\r\n    Else\r\n        WindowProc = CallWindowProc(PrevProc, hWnd, uMsg, wParam, lParam)\r\n    End If\r\n\r\nEnd Function\r\n\r\n' Funci\u00f3n Privada del m\u00f3dulo.\r\nPrivate Function GetHostByNameAlias(ByVal HostName As String) As Long\r\n\r\n    On Error Resume Next\r\n    Err.Clear\r\n\r\n    Dim heDestHost As HostEnt\r\n    Dim addrList As Long\r\n    Dim retIP As Long\r\n    Dim phe As Long\r\n\r\n    retIP = inet_addr(HostName)\r\n\r\n    If retIP = INADDR_NONE Then\r\n        phe = gethostbyname(HostName)\r\n        If phe &lt;&gt; 0 Then\r\n            MemCopy heDestHost, ByVal phe, 16\r\n            MemCopy addrList, ByVal heDestHost.hAddrList, 4\r\n            MemCopy retIP, ByVal addrList, heDestHost.hLen\r\n        Else\r\n            retIP = INADDR_NONE\r\n        End If\r\n    End If\r\n\r\n    GetHostByNameAlias = retIP\r\n\r\n    If Err Then GetHostByNameAlias = INADDR_NONE\r\nEnd Function\r\n\r\n'Funcion Privada del m\u00f3dulo\r\nPrivate Function GetAscIp(ByVal inn As Long) As String\r\n    On Error Resume Next\r\n    Dim lpStr&amp;\r\n    Dim nStr&amp;\r\n    Dim retString$\r\n\r\n    retString = String(32, 0)\r\n\r\n    lpStr = inet_ntoa(inn)\r\n    If lpStr = 0 Then\r\n        GetAscIp = &quot;255.255.255.255&quot;\r\n        Exit Function\r\n    End If\r\n    nStr = lstrlen(lpStr)\r\n    If nStr &gt; 32 Then nStr = 32\r\n    MemCopy ByVal retString, ByVal lpStr, nStr\r\n    retString = Left(retString, nStr)\r\n    GetAscIp = retString\r\n    If Err Then GetAscIp = &quot;255.255.255.255&quot;\r\nEnd Function\r\n\r\n'*=====================ATENCION=====ATENCION======ATENCION=======================*\r\n'*===============================================================================*\r\n'*===============================================================================*\r\n'ESTAS LINEAS DEBEN IR EN EL FORMULARIO O MODULO CLASE DONDE RECIBIRAN LOS EVENTOS\r\n'*===============================================================================*\r\n'*===============================================================================*\r\n'_________________________________________________________________________________________________\r\n\r\n'Public Sub Socket_Conect(ID As Long, IP As String, Puerto As String)\r\n'End Sub\r\n'_________________________________________________________________________________________________\r\n\r\n'Public Sub Socket_DataArrival(ID As Long, IP As String, Puerto As String, Data As String)\r\n'End Sub\r\n'_________________________________________________________________________________________________\r\n\r\n'Public Sub Socket_Close(ID As Long, IP As String, Puerto As String)\r\n'End Sub\r\n'_________________________________________________________________________________________________\r\n<\/pre>\n<\/p>\n<p style=\"text-align: center;\"><span style=\"text-decoration: underline;\"><em>Ejemplo: Cliente &#8211; Servidor (Chat)<\/em><\/span><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/www.leandroascierto.com\/blog\/imagenes\/Servidor.png\" alt=\"Webcam\" width=\"529\" height=\"521\" \/><\/p>\n<p align=\"center\"><a href=\"https:\/\/leandroascierto.com\/blog\/descarga.php?url=Cliente_Servidor.zip\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"Descargar\" src=\"https:\/\/leandroascierto.com\/blog\/descarga.php?file=Cliente_Servidor.zip\" alt=\"\" width=\"280\" height=\"61\" \/><\/a><\/p>\n<\/p>\n<p style=\"text-align: center;\"><span style=\"text-decoration: underline;\"><em>Ejemplo: Cliente &#8211; Servidor (Transferencia de archivos)<\/em><\/span><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/www.leandroascierto.com\/blog\/imagenes\/Transferencia_Archivos.png\" alt=\"Webcam\" width=\"532\" height=\"309\" \/><\/p>\n<p align=\"center\"><a href=\"https:\/\/leandroascierto.com\/blog\/descarga.php?url=Transferencia_de_Archivos.zip\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"Descargar\" src=\"https:\/\/leandroascierto.com\/blog\/descarga.php?file=Transferencia_de_Archivos.zip\" alt=\"\" width=\"280\" height=\"61\" \/><\/a><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Este es un m\u00f3dulo para trabajar con los Socket de Windows, vendr\u00eda a ser un reemplazo del WinSock.ocx, en este me he basado en el m\u00f3dulo de\u00a0KPD-Team\u00a0y lo reform\u00e9 a mi gusto. Su uso creo, es muy sencillo y pr\u00e1ctico, especialmente a la hora de trabajar con m\u00faltiples conexiones, si lo utilizan tal vez puedan <a href='https:\/\/leandroascierto.com\/blog\/winsock32\/' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29],"tags":[79],"class_list":["post-219","post","type-post","status-publish","format-standard","hentry","category-modulos","tag-sokets","category-29-id","post-seq-1","post-parity-odd","meta-position-corners","fix"],"_links":{"self":[{"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/posts\/219","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/comments?post=219"}],"version-history":[{"count":10,"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/posts\/219\/revisions"}],"predecessor-version":[{"id":574,"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/posts\/219\/revisions\/574"}],"wp:attachment":[{"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/media?parent=219"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/categories?post=219"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/leandroascierto.com\/blog\/wp-json\/wp\/v2\/tags?post=219"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}