PDA

Click to See Complete Forum and Search --> : Winsock: make a server that can use senddata


error 404
Dec 27th, 2008, 04:12 AM
Hi,
I have this part of code (server) for DataArrival:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim stringa, r, username, password, U, P As String
Dim AryData() As String

Winsock1.GetData stringa, vbString

AryData = Split(stringa, ",")
U = AryData(0)
P = AryData(1)

Open "C:\dati.dat" For Input As #1
txtUsername.Text = U
txtPassword.Text = P

Do While Not EOF(1)
Input #1, username, password
If username = U And password = P Then
r = "OK"
Else
r = "ERROR"
End If
Loop

Close #1

txtRisposta.Text = r
Winsock1.SendData r

End Sub

And this for client:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim stringa, r As String

Winsock1.GetData stringa, vbString

txtRecvData.Text = r

If r = "ERROR" Then
MsgBox "Non sei registrato", vbOKOnly, "Errore"
End If
If r = "OK" Then
MsgBox "Hai effettuato l'accesso", vbOKOnly, "OK"
End If

End Sub

I don't know, but the client don't receive the variable "r".

Why?

Sorry, but I'm new of Winsock :sick:

(If you need whole code, tell me)

Thanks, bye

Doogle
Dec 28th, 2008, 03:31 AM
There are some 'newbie' style problems with your code.
1.

Dim stringa, r, username, password, U, P As String

Only P will be defined as a String, all the others on the line will be defined as Variants. You'll need something like:

Dim stringa As String, r As String, username As String
Dim password As String, U As string, P As String

I assume these definitions are in the Declarations Section of the Form since U and P are used in the DataArrival event but not set to any value there.
2.

Open "C:\dati.dat" For Input As #1

You are assuming that #1 is an available file handle. It may or may not be. It would be safer to use the FreeFile Function which will always return a free handle

Dim intFile As Integer
intFile = FreeFile
Open "C:\dati.dat" For Input As #intFile

and use #intFile instead of #1 when performing the I/O functions
3.

Do While Not EOF(1)
Input #1, username, password
If username = U And password = P Then
r = "OK"
Else
r = "ERROR"
End If
Loop

Will always set r to "ERROR" unless the last record in the file matches the given username and password. You should exit the loop once you've found a match. For example

r = "ERROR"
Do
Input #intFile, username, password
If username = U And password = P Then
r = "OK"
EndIf
Loop Until r = "OK" or EOF(#intFile)

4. I've left this 'till last as it's more complicated that the above. When you're using Winsock, data will arrive in 'dribs and drabs' since TCP is stream orientated rather than record orientated.

Although you may send username,password in one SendData it will not necessarily all arrive together in one DataArrival event. You may get username, in one DataArrival event and password in the next one. Your code has to take that possibility into account. A common method is to buffer the incoming data until you know that a complete record has arrived. In order to know that, it's necessary to terminate each record with an End of Record character (eg vbCr). Once you see a vbCr in the buffer, you know that at least one complete record has arrived so you can then extract it from the buffer and process it.
Here's a simple DataArrival event which buffers the data until a vbCr is received.

Static strBuffer As String
Dim strData As String
Dim strRecord As String
Dim aryData() As String
Dim intPos As Integer
Dim boComplete As Boolean
'
' Read the Data and append it to the Buffer
'
Winsock1.GetData strData
strBuffer = strBuffer & strData
Do
'
' Is there a vbCr in the Buffer?
' if there is then intPos will equal it's position
' in the buffer, otherwise it will be zero
'
intPos = InStr(strBuffer, vbCr)
If intPos > 0 Then
'
' Yes, we have at least one complete record
' unblock it into strRecord
'
strRecord = Mid$(strBuffer, 1, intPos-1)
'
' Get the username and password that was sent
'
aryData = Split(strRecord, ",")
'
' Now you can insert the code to check the
' username and password with aryData(0) and aryData(1)
' Once you've done that (and Closed #intFile)
'
' Is there anything else in the Buffer?
'
If intPos < Len(strBuffer) Then
'
' Yes, move it to the front of the buffer
' and go round the Do Loop again
' to process it
'
strBuffer = Mid$(strBuffer, intPos + 1)
Else
'
' No, then flush the buffer
' and signal to exit the loop
'
strBuffer = ""
boComplete = True
End If
Else
'
' vbCr is not in the buffer, just exit
' and wait for the next DataArrival event
'
boComplete = True
End If
Loop Until boComplete = True

If you use the above code then you should always put a vbCr at the end of each record you send.
For example

Winsock1.SendData username & "," & password & vbCr

Hope that helps.

Nightwalker83
Dec 31st, 2008, 12:41 AM
Here is code I wrote years ago that might help:

http://www.vbforums.com/showthread.php?t=236973

error 404
Jan 1st, 2009, 04:00 PM
Thanks you both!

I have another problem: how can I use Winsock's command (like SendData) in more form?
Example: I have 2 form, form1 and form2. form1 have Winsock1; I want send data from form2 without create another Winsock. It's possible? If yes, how?

Thanks

Nightwalker83
Jan 2nd, 2009, 12:19 AM
If I remember correctly (been years since I've done VB)!


form1.winsock


would be the control. If you then want a text box on form 2 to display the message it would be:


text1.text = form1.winsock1.getdata text


text would be the data you are receiving.

error 404
Jan 2nd, 2009, 12:14 PM
It doesn't work :(

Nightwalker83
Jan 2nd, 2009, 06:57 PM
It doesn't work :(

Using the example linked to above!


'Client code

Dim str As String

Private Sub Command2_Click()

Winsock1.SendData "|MESSAGE|" & Text2.Text

End Sub

Private Sub Command1_Click()

Winsock1.Connect Text1.Text, "1001"

End Sub

'Server code

Dim str As String

Private Sub Form_Load()

Winsock1.LocalPort = 1001
Winsock1.Listen
End Sub

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
Winsock1.Accept requestID
End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Winsock1.GetData str
If InStr(1, str, "|MESSAGE|") <> 0 Then
message = Mid$(str, "10", Len(str))
Text1.Text = message
End If
End Sub


Just change the server winsock control to the form that it's on.

example:


form2.Winsock1.GetData str


DON'T FORGET: Declare the variable!

example:

Dim str As String