Winsock è un po' un casino... ho scaricato un po' di codice, e ci sono delle cose che non capisco.... inoltre mi da un errore...
posto il codice client:
codice:
Private Sub Form_Load()
tcpClient.RemoteHost = m_strNomeServer
' io leggo il m_strNomeServer dal Registry; potrebbe anche essere
' il nome del computer sulla rete (LAN o WAN)
tcpClient.RemotePort = 1001
If tcpClient.State = sckClosed Then
tcpClient.Connect
' Questa.Connect scatena l'evento ConnectionRequest sul prg Server
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
If tcpClient.State <> sckClosed Then
If tcpClient.State = sckConnected Then
' PRIMA di disconnettermi quasi "fisicamente" dal server
' gli comunico che mi sto disconnettendo
' Questo non è obbligatorio per il controllo Winsock,
' ma per il mio applicativo sì!
ComponiComando tcpClient, g_str_PKT_CMD_CONN_END, 0, m_strUserID
End If
tcpClient.Close
End If
End Sub
Private Sub tcpClient_Connect()
' appena collegato quasi "fisicamente", comunico al server chi sono
' La ComponiComando è identica a quella del server
ComponiComando tcpClient, g_str_PKT_CMD_CONN_START, 0, m_strUserID
' Questa istruzione scatenza l'evento DataArrival sul server
End Sub
Private Sub tcpClient_DataArrival(ByVal bytesTotal As Long)
Dim strRicevuta As String
' l'intera stringa ricevuta
tcpClient.GetData strRicevuta
' Qui mi gestisco la stringa ricevuta in maniera simile (attenzione:
' non identica!) a quanto faccio nel server
End Sub
Private Sub tcpClient_Error(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)
' In caso di errore, chiudo tutto
tcpClient.Close
MsgBox "tcpClient_Error:" & CStr(Number) & m_strNomeServer
Unload Me
End Sub
non capisco cosa sia componicomando (e li mi da errore)... non capisco neanche con il codice del server cosa sia comando, ma li non mi da errore!!!
posto il codice server:
codice:
aPrivate Sub tcpServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
Dim blnTrovato As Boolean
Dim intIndice As Integer
blnTrovato = False
If Index = 0 Then ' E' un tentativo di connessione al server
intIndice = 1
' Loopo sulle 4 connessioni per cercarne 1 libera
Do Until ((blnTrovato = True) Or (intIndice > 4))
If tcpServer(intIndice).State = sckClosed Then
tcpServer(intIndice).Accept requestID
‘ Questa Accept scatena l’evento Connect sul client
blnTrovato = True
Else
intIndice = intIndice + 1
End If
Loop
End If
End Sub
Private Sub tcpServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim strRicevuta As String 'l'intera stringa ricevuta
' I componenti della comunicazione client/server
' strComandoPacchetto + lngDimensionePacchetto + strDatiPacchetto,
' nel caso di comunicazioni tra client e server
' in entrambe le direzioni
' strDatiPacchetto, se il client sta inviando i dati che compongono una tabella
Dim strComandoPacchetto As String
Dim lngDimensionePacchetto As Long
Dim strDatiPacchetto As String
On Error GoTo GestErrore
tcpServer(Index).GetData strRicevuta
strComandoPacchetto = Left(strRicevuta, g_int_DIMENSIONE_COMANDO)
strDatiPacchetto = RTrim(Right(strRicevuta, g_int_DIMENSIONE_DATI))
lngDimensionePacchetto = Val(Mid(strRicevuta, g_int_DIMENSIONE_COMANDO + 1, _
g_int_DIMENSIONE_NUMERO))
Select Case strComandoPacchetto
Case g_str_PKT_CMD_CONN_START Then
StrUserID = strDatiPacchetto
' l’applicazione (dopo TCP!) riconosce l’utente
' e gli conferma “Benvenuto”
ComponiComando Index, g_str_PKT_CMD_CONN_CONF, 0, ""
Case g_str_PKT_CMD_CONN_END
' l’utente si è disconnesso dalla mia applicazione PRIMA che da TCP
Case g_str_PKT_CMD_CONN_CONF
' il server INVIA questo messaggio, perciò non deve gestirne la ricezione
Case g_str_PKT_CMD_TRX_START
' il client sta per trasmettermi un file, il cui nome è in strDatiPacchetto
Open strDatiPacchetto For Binary As Index
' il server dice “Ho ricevuto il file x per un totale
' di 0 Bytes”; il client lo interpreta come: “Ok, trasmetti!”
ComponiComando Index, g_str_PKT_CMD_TRX_CONF, 0, m_strNomeTabella
Case g_str_PKT_CMD_TRX_CONF
Select Case lngDimensionePacchetto
Case 0 ' Bisogna inviare il file
Invia tcpServer(Index), m_strNomeFileDati
Case m_lngBytesAttesi
' Il file è arrivato correttamente
' Nella mia applicazione, passo alla tabella successiva
' (ho un elenco nel registry)
Case Else ' Occorre dire al client di riinviare il file
ComponiComando Index, g_str_PKT_CMD_TRX_START, m_lngBytesAttesi,_
m_strNomeFileDati
End Select
Case g_str_PKT_CMD_TRX_END
' Import nel database dei dati ricevuti dall’agente
ImportaFilesXML m_strUserID(Index)
' Export dei dati da inviare all’agente
EsportaFilesXML m_strUserID(Index)
' trasmissione dei dati elaborati
m_lngBytesRicevuti = 0
m_lngBytesAttesi = FileLen(m_strNomeFileDati)
ComponiComando Index, g_str_PKT_CMD_TRX_START, m_lngBytesAttesi, _
m_strNomeFileDati
Case Else ' trattasi dei dati veri e propri
Put Index, , strDatiPacchetto
m_lngBytesRicevuti = m_lngBytesRicevuti + Len(strDatiPacchetto)
If m_lngBytesAttesi = m_lngBytesRicevuti Then
Close Index
ComponiComando Index, g_str_PKT_CMD_TRX_CONF, m_lngBytesRicevuti,_
m_strNomeTabella
End If
End Select
Exit Sub
GestErrore:
ScriviSuLog g_strNomeFileLog, Index, _
"tcpServer_DataArrival error " & Err.Number & vbCrLf & Err.Source, 0
End Sub
In caso di errori viene scatenato l’evento Error; nella mia realtà non uso però una MsgBox, perché l’applicazione è NON presidiata e rischierei, bensì una routine ScriviSuLog(strNomeFileLog, strUtente, Number, Description, etc)
Private Sub tcpServer_Error(Index As Integer, 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)
MsgBox "tcpServer_Error: " & CStr(Number) & vbCrLf & Description
End Sub
La Close chiude la singola connessione; ad esempio, se l'agente che sta utilizzando la connessione n°3 si scollega, questo evento verrà attivato dal metodo Close del Client; sul server Index varrà ... 3!
Private Sub tcpServer_Close(Index As Integer)
If tcpServer(Index).State <> sckClosed Then
tcpServer(Index).Close
End If
End Sub
Private Sub InviaStringa(Index As Integer, Comando As String, Dimensione As Long, _
Dati As String)
' Comando, Dimensione e Dati sono miei parametri per costruirmi la
' stringa che "viaggia" tra i due programmi che risulta
' composta da Comando (10 char) + Dimensione (14 char) + Dati (1000 char)
tcpServer(Index).SendData Comando & Space(g_int_DIMENSIONE_COMANDO - Len(Comando)) & _
Format(Dimensione, g_str_PKT_NUMBER_MASK) & _
Space(g_int_DIMENSIONE_HEADER - Len(Comando) - Len(g_str_PKT_NUMBER_MASK)) & _
Dati & Space(g_int_DIMENSIONE_DATI - Len(Dati))
' La tcpServer(Index).SendData scatena l'evento DataArrival sul client
End Sub
Private Sub Form_Load()
tcpServer(0).LocalPort = 1001
tcpServer(0).Listen 'il Server "ascolta" la porta impostata sopra
For intIndice = 1 To 4
Load tcpServer(intIndice) ' creo la nuova istanza
tcpServer(intIndice).LocalPort = 0 ' TASSATIVO punto e basta
Next
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim intIndice As Integer
For intIndice = 1 To 4
Unload tcpServer(intIndice)
Next
End Sub
boh....
comunque ringrazio anticipatamente anche xegallo... il codice è molto breve!!!
e grazie anche per hostname!
PS: con winsock, si inviano anche file e/o comandi????
THANKS