Vamos a ver en principio la aplicación Servidor.
Tienes que insertar un control Winsock en el formulario que controle las conexiones, le pones en la propiedad INDEX = 0 y le asignas un puerto.Al cargar la aplicación lo pones a la escucha y fíjate bien que, en este caso concreto, el puerto sería siempre 32000 (Ojo que no puedes usar un puerto que ya esté en servicio porque colisionaría).
Código:
'Activar Puertos de escucha
Me.ThreadReceiver(0).LocalPort = 32001
Me.ThreadReceiver(0).Listen
DoEvents
Un cliente tratará de conectarse de la siguiente forma, donde threadServer es el nombre o la IP del equipo servidor a la escucha.
Código:
'Conectar con el controlador de Hilos
Me.ThreadSocket.RemoteHost = threadServer
Me.ThreadSocket.RemotePort = 32001
Me.ThreadSocket.Connect
DoEvents
y El servidor reaccionará de la siguiente manera para activar la petición
Código:
Private Sub ThreadReceiver_ConnectionRequest(Index As Integer, ByVal requestID As Long)
Dim ActIndex As Integer
Dim iniBytes As String
Dim nd As Node, idx As Long
On Local Error Resume Next
Err.Clear
If Index = 0 Then
'Comprobar si se puede aprovechar
'una conexión cerrada.
If HashReceiver.Count <> 0 Then
ActIndex = HashReceiver.Item(1): HashReceiver.Remove (1)
Else
ActIndex = idReceiver + 1
idReceiver = idReceiver + 1
End If
'Aceptar la conexión
Load ThreadReceiver(ActIndex)
ThreadReceiver(ActIndex).LocalPort = 0
ThreadReceiver(ActIndex).Accept requestID
DoEvents
'Analizar si existe alguna tarea asignada
Err.Clear
idx = Me.TreeThreads.Nodes((LCase(ThreadReceiver(ActIndex).LocalHostName) + "TASK")).Index
If Err Or idx = 0 Then
Set nd = Me.TreeThreads.Nodes.Add(LCase(ThreadReceiver(ActIndex).LocalHostName), tvwChild, (LCase(ThreadReceiver(ActIndex).LocalHostName) + "TASK"), "Multi-Task", 4)
nd.Expanded = True
End If
Err.Clear
'Asignar nodode tarea al árbol
Set nd = Me.TreeThreads.Nodes.Add((LCase(ThreadReceiver(ActIndex).LocalHostName) + "TASK"), tvwChild, (LCase(ThreadReceiver(ActIndex).LocalHostName) + "TASK" + Format(ActIndex, "0000")), "Thread_" + Format(ActIndex, "0000"), 6)
nd.Expanded = True
End If
DoEvents
End Sub
Private Sub ThreadReceiver_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim strData As String
Dim spa As Variant, spb As Variant
On Local Error Resume Next
ThreadReceiver(Index).GetData strData
DoEvents
spa = Split(strData, "|")
Select Case UCase(CStr(spa(0)))
Case "[INIT]"
spb = Split(CStr(spa(1)), ";")
Me.TreeThreads.Nodes((LCase(ThreadReceiver(Index).LocalHostName) + "TASK" + Format(Index, "0000"))).Text = CStr(spb(2)) + "::" + CStr(spb(1))
Case "[END]"
Me.TreeThreads.Nodes.Remove ((LCase(ThreadReceiver(Index).LocalHostName) + "TASK" + Format(Index, "0000")))
HashReceiver.Add Index, ("K" + CStr(Index))
Me.ThreadReceiver(Index).Close: DoEvents
End Select
End Sub
Como puedes ver la petición de conexión siempre se realiza por el INDEX 0 del Array de sockets, Verifico si puedo recuperar uno cerrado (Lo controlo con un Collection) y si no hay idsponibles cargo un nuevo elemento del array y acepto el RequestID solicitado.
A partir de este momento cualquier dato enviado mediante SENDDATA en cualquiera de los sentidos, será recibido por el evento DataArrival.
Que usuario te envía los datos lo puedes controlar por el valor INDEX y si más de un usuario envía al mismo tiempo, recibiras cada petición por el canal adecuado.
No se te olvide poner DOEVENTS para obligar al SO a terminar cualquier proceso pendiente, de lo contrario el mensaje puede quedar en cola hasta que windows decida enviarlo.
Prueba primeramente con esto que te apunto en dos aplicaciones sencillas Server-Cliente y comprenderás como se comporta.
NOTA: en mi código utilizo cosas que no tendrás en tú aplicación, por lo tanto elimina todas las referencias que no encuentre