Page 1
Page 2
Page 3
We will now add some code to the 'Send'
button. We want to send a stream of data to the server we
are connected to, and just receive it back and display it.
We will add a fancy touch, so that we can tell the server
to reset itself, and wait for another connection.
Private Sub cmdSend_Click()
If Len(Trim(txtSendData)) = 0 Then
MsgBox _
"Please enter some data to send to the host!"
_
, vbInformation, "No Data"
Exit Sub
End If
sbuff = txtSendData
'
' Send the data to the server, and tell it
' how much to expect
'
iret = Cesend(isocket, sbuff, Len(sbuff), 0)
If iret <> 0 Then
MsgBox _
"Error returned from Cesend - " & iret, _
vbCritical, "Cesend"
Exit Sub
End If
'
' The server will send us the data back
' iret will give us the length in bytes
' of the data sent back
'
rbuff = Space(Len(sbuff))
iret = Cerecv(isocket, rbuff, Len(sbuff), 0)
If iret < 1 Then
MsgBox _
"Error returned from Cerecv - " & iret, _
vbCritical, "Cerecv"
Exit Sub
End If
txtRecData = rbuff & vbCrLf
End Sub
Add some code to do the server 'reset'
Private Sub cmdReset_Click()
sbuff = "RESET"
iret = Cesend(isocket, sbuff, Len(sbuff), 0)
If iret <> 0 Then
MsgBox "Error returned from Cesend - " _
& iret, vbCritical, "Cesend"
Exit Sub
End If
cmdSend.Enabled = False
cmdRecv.Enabled = False
cmdReset.Enabled = False
cmdConnect.Enabled = True
End Sub
When the server gets the 'reset' command,
it will close its socket, and go back to listen for a connection.
Add a couple of routines to translate an ip address to a
host name, and a host name to an ip address.
private Sub cmdGetHostName_Click()
If Len(Trim(txtIp)) <> 0 Then
hostname = Space(30)
hostip = txtIp
iret = Cegethostbyaddr(hostip, hostname)
If iret <> 0 Then
MsgBox "Error in gethostbyaddr - " & _
iret, vbCritical, "Error in call"
Else
txtHname = hostname
End If
Else
MsgBox "Please enter an ip address", _
vbInformation, "IP Please"
txtIp.SetFocus
End If
End Sub
Private Sub cmdNameToIp_Click()
If Len(Trim(txtHname)) <> 0 Then
hostip = Space(30)
hostname = txtHname
iret = CeGetIpAddress(hostname, hostip)
If iret <> 0 Then
MsgBox "Error in getipaddress - " _
& iret, vbCritical, "Error in call"
Else
txtIp = hostip
End If
Else
MsgBox "Please enter a host name", _
vbInformation, "IP Please"
txtHname.SetFocus
End If
End Sub
You may find that these routines may
not work. They only work for me on the Pocket PC when I
use my PC's IP address as the Wins Server. There are more
details about this in various places. Look up on http://groups.google.com/
for ethernet and activesync.
Now a bit of code behind the 'recv'
button. This will allow us to receive ad-hoc data sent from
the server.
Private Sub cmdRecv_Click()
rbuff = Space(512)
iret = Cerecv(isocket, rbuff, 50, 0)
If iret < 1 Then
MsgBox "Error returned from Cerecv - " _
& iret, vbCritical, "Cerecv"
Exit Sub
End If
txtRecData = rbuff
End Sub
And finally, some code for closing down...
Private Sub Form_OKClick()
'
' Close our socket
'
If isocket <> 0 Then
iret = Ceclosesocket(isocket)
iret = CeWSACleanup()
End If
App.End
End Sub
That is now it - a TCP/IP client, using
the sockets API.
Here is the client

Talking to the server

So why have we gone to all this
trouble, when the winsock control is so easy to use.
There are well document problems with the winsock control.
The dataarrival event sends back one byte, and then the
rest of the data. Binary data is not handled, so we have
to bring back a byte array, and turn it back to a string.
Whilst testing my own server software with the winsock control,
I had to increase the number of recv's I did on the server,
as the winsock control sends its data in dribs and drabs.
Using the API overcomes these
problems, at the overhead of a more complex source.
I'M STILL NOT CONVINCED PETE!!
Well, maybe this will convince you.
I needed an excuse to write this dll, and I thought "it
should perform better than the ocx". Actually I really
thought, "it can't perform worse!". So after finishing
the above project, and testing it, I thought I had better
compare the performance. I wrote a small evb application,
which connected to the VB server, and then sent and received
512 bytes of data eight times, to move 4kb of data. Using
'timer', I took the time at the start, again at the end
and displayed the results. I even took the 'translate buffer'
routine out, and used "winsock.getdata strbuff, vbstring",
so there was no overhead involved in translating binary
data. I then 'bent' the client program from this article,
to do the same thing.
This message box is from the Winsock
version

and this one is from the sockets
dll version

I was staggered by this, and
watching the server perform, winsock may take over 100 'sends'
before it can send the 512 bytes. The source code of the
'winsock' application is included so that you can do your
own comparisons. I would be very interested to hear of the
results!
Due to my rudimentary knowledge of C++,
I posted various questions in the news groups, and received
very gracious help from Alexandre Baccarin, Geoffrey Kneller,
Pankaj Neurayal and others. Thanks for your patience gents.
The cesockets.dll is available free
for personal use. For a commercial licence, please visit
my web site at www.gui-innovations.com
Previous Page