Tech Note 03d: WinSock

September 15, 2007

© NSB Corporation. All rights reserved.

There is additional documentation on Microsoft's website..

NS Basic/CE allows you to access the internet using Microsoft's standard WinSock object. Make sure it is installed on your Windows CE device and that it is properly set up in the Registry. See Tech Note 01 for more information on how to load this module onto your system.

Before using winsock, you need to initialize it using the following command:

addObject "winsock"

 

Notes

These are notes submitted by users. We have not verified these are true on all cases. 1. "I've been trying to get the MS WINSOCK control to work correctly. It stops receiving incoming message after the first one. So I downloaded IP*Works 5 (I own version 4) and installed the ocx on my iPAQ 3955. I changed the Object name, method names, and parameters and it worked the first time!!!

One thing that I find really cool, is that when the PocketPC is connected on the USB port, the connection is treated as a TCP connection. So I can connect to TCP port servers on my NT/2000 machines and exchange data using a USB connection, a network card, or an RF card without changing a line of code. Very nice. I can utilize the PocketPC as an intelligent client. I have TCP servers that interact with Access, SQL Server and Oracle databases. This allows multi-tier developement without the overhead of MS's libraries and complex technology."

2. Using Winsock on a WiFi connection:
"Even if the IP address of the system you are connecting to has nothing to do with the internet, winsock.connect needs a connection to a DNS server to figure this out (or an 80 second delay). I guess this is a MS issue, perhaps they could re-write the winsock to try local addresses prior to querying a DNS server."

3. Using Winsock when a connection has not been established:
"When working with a phone connection or WiFi, a Connection needs to be established before Winsock will work. Follow Microsoft's or your carrier's instructions for setting up the Connection in Settings...System...Communications...Connections. You can establish the connection using the sample code in "Establishing a Connection" below."

Properties

Properties either set or return values. The syntax is

Winsock.bytesReceived 'get the number of bytes received

 

BytesReceived

Gets the number of bytes in the receive buffer

LocalHostName

Gets the string name of the local host

LocalIP

Gets IP address in the form "255.255.255.255"

LocalPort GetData

Gets/sets the local port. Use 0 to grab a random one.

Protocol

Gets/sets Protocol. 0=TCP, 2=IRDA

RemoteHost

Gets/sets remote host name

RemoteHostIP

Gets/sets remote host IP address

RemotePort

Gets/sets remote port to connect to. 80 is webserver. See complete list in Appendix A.

SocketHandle

Gets socket handle used to communication with Winsock layer

State

0-closed
1-open
2-listening
7-connected
9-error

ServiceName

Gets/sets name of service

 

Methods

 

Accept

Accepts an incoming connection (from ConnectionRequest event)

Close

Close the connection. Returns number of errors

Connect

Established connection. Returns 0 if successful

GetData

Returns current block of data.

Listen

Creates a socket and puts it into listen mode

SendData(data)

Sends data to a remote computer

 

Events

Events cause subroutines in your program to be called, if they exist. You should name the subroutine <objectName>_eventName.

For example, to capture clicks in the Output Object, you will need

sub winsock_dataArrival
'your code to handle a data arriving
end sub

 

Close

Connection closed by remote computer. Do a local close method.

ConnectionRequest

Remote computer request connection. Sets RemoteHostIP, RemoteHost

DataArrival(n)

Data has been received. n is how many.

Error(e)

Error code. See Appendix B for listing

SendComplete

Sent when SendData completes

SendProgress(b,r)

While data is being sent. B=bytes sent, r- bytes remaining

 

Remarks

The Transfer Control Protocol (TCP) allows you to create and maintain a connection to a remote computer. Using the connection, the computers can exchange data.

Client applications need to know the server computer's name or IP address (RemoteHost property), as well as the port (RemotePort property) on which it will be listening. Invoke the Connect method to make the connection.

Server applications need to set the port (LocalPort property) on which to listen, and invoke the Listen method. When the client requests a connection, the ConnectionRequest event is sent. Invoke the Accept method within the ConnectionRequest event to complete the connection.

Once a connection has been made, either computer can send and receive data. Use the SendData method to send data. Whenever data is received, the DataArrival event occurs. Use the GetData method within your DataArrival subroutine to retrieve the data.

Sample

rem show a simple retrieval of a web page
addobject "winsock.winsock.1","winsock"
winsock.remotehost="www.nsbasic.com"
winsock.remoteport=80
winsock.connect
strData="GET http://www.nsbasic.com/ce/PR/pr.981012.html" & vbCrLf & vbCrLf
print strData
winsock.sendData strData

sub winsock_DataArrival(byval bytesTotal)
  dim rdata
  print "data arrival"
  winsock.getData rData
  print rData
  if winsock.state = 8 then
     winsock.close
  End if.
end sub

sub winsock_error(code, desc)
  print "winsock error:" & code & " " & description
end sub

 

Appendix A: List of Standard Port Numbers

tcpmux          1/tcp                           # TCP port multiplexer 
(RFC1078)
echo            7/tcp
echo            7/udp
discard         9/tcp           sink null
discard         9/udp           sink null
systat          11/tcp          users
daytime         13/tcp
daytime         13/udp
netstat         15/tcp
qotd            17/tcp          quote
chargen         19/tcp          ttytst source
chargen         19/udp          ttytst source
ftp             21/tcp
telnet          23/tcp
smtp            25/tcp          mail
time            37/tcp          timserver
time            37/udp          timserver
rlp             39/udp          resource        # resource location
nameserver      42/tcp          name            # IEN 116
whois           43/tcp          nicname
domain          53/tcp          nameserver      # name-domain server
domain          53/udp          nameserver
mtp             57/tcp                          # deprecated
bootps          67/udp          bootp           # bootp server
bootpc          68/udp                          # bootp client
tftp            69/udp
gopher          70/tcp
rje             77/tcp          netrjs
finger          79/tcp
link            87/tcp          ttylink
webserver       80/tcp
supdup          95/tcp
hostnames       101/tcp         hostname        # usually from sri-nic
tsap            102/tcp                         # part of ISODE.
pop2            109/tcp                         # old pop port
pop             110/tcp         pop3 postoffice
sunrpc          111/tcp
sunrpc          111/udp
ident           113/tcp         auth tap authentication
sftp            115/tcp
uucp-path       117/tcp
nntp            119/tcp         readnews untp   # USENET News Transfer 
Protocol
ntp             123/udp         ntpd
imap            143/tcp
snmp            161/udp                         # network time protocol
snmp-trap       162/udp
smux            199/tcp

 

Appendix B: Error codes returned by ERROR event

 

sckOutOfMemory

7

Out of memory.

sckInvalidPropertyValue

380

The property value is invalid.

sckGetNotSupported

394

The property cannot be read.

sckSetNotSupported

383

The property is read only.

sckBadState

40006

Wrong protocol or connection state for the requested transaction or request.

sckInvalidArg

40014

The argument passed to a function was not in the correct format or in the specified range.

sckSuccess

40017

Successful.

sckUnsupported

40018

Unsupported variant type.

sckInvalidOp

40020

Invalid operation at current state.

sckOutOfRange

40021

Argument is out of range.

sckWrongProtocol

40026

Wrong protocol for the requested transaction or request.

sckOpCanceled

1004

The operation was canceled.

sckInvalidArgument

10014

The requested address is a broadcast address, but flag is not set.

sckWouldBlock

10035

Socket is non blocking and the specified operation will block.

sckInProgress

10036

A blocking Winsock operation in progress.

sckAlreadyComplete

10037

The operation is completed. No blocking operation in progress.

sckNotSocket

10038

The descriptor is not a socket.

sckMsgTooBig

10040

The datagram is too large to fit into the buffer and is truncated.

sckPortNotSupported

10043

The specified port is not supported.

sckAddressInUse

10048

Address in use.

sckAddressNotAvailable

10049

Address not available from the local machine.

sckNetworkSubsystemFailed

10050

Network subsystem failed.

sckNetworkUnreachable

10051

The network cannot be reached from this host at this time.

sckNetReset

10052

Connection has timed out when SO_KEEPALIVE is set.

sckConnectAborted

11053

Connection is aborted due to timeout or other failure.

sckConnectionReset

10054

The connection is reset by remote side.

sckNoBufferSpace

10055

No buffer space is available.

sckAlreadyConnected

10056

Socket is already connected.

sckNotConnected

10057

Socket is not connected.

sckSocketShutdown

10058

Socket has been shut down.

sckTimedout

10060

Socket has been shut down.

sckConnectionRefused

10061

Connection is forcefully rejected.

sckNotInitialized

10093

WinsockInit should be called first.

sckHostNotFound

11001

Authoritative answer:Host not found.

sckHostNotFoundTryAgain

11002

Non Authoritative answer: Host not found.

sckNonRecoverableError

11003

Non recoverable errors.

sckNoData

11004

Valid name, no data record of requested type.

Establishing a Connection

When working with a phone connection or WiFi, a Connection needs to be established before Winsock will work. Follow Microsoft's or your carrier's instructions for setting up the Connection in Settings...System...Communications...Connections.

This code assumes you have set up the connection.

ShowOKButton true

Declare "Function ConnMgrMapURL Lib ""Cellcore.dll"" (ByVal URL as string, byRef Guid() as Long, byVal Index as Long) as Integer"
Declare "Function ConnMgrEstablishConnectionSync lib ""cellcore.dll"" (byRef ConnectionInfo() as long, byRef Connection as long, byVal Timeout as long, byRef Status as long) as Integer"
Const S_OK = 0
Const CONNMGR_PARAM_GUIDDESTNET = &h1 
Const CONNMGR_FLAG_PROXY_HTTP = &h1
Const CONNMGR_PRIORITY_USERINTERACTIVE = &h08000 
Const CONNMGR_STATUS_CONNECTED = &H10

'This is a CONNMGR_CONNECTIONINFO structure. See MSDN for details
Dim ConnectionInfo(15)
For i=0 To 15
  ConnectionInfo(i)=CLng(0)
Next
ConnectionInfo(0)=CLng(16*4)                             'cbSize
ConnectionInfo(1)=CLng(CONNMGR_PARAM_GUIDDESTNET)        'dwParams
ConnectionInfo(2)=CLng(CONNMGR_FLAG_PROXY_HTTP)          'dwFlags
ConnectionInfo(3)=CLng(CONNMGR_PRIORITY_USERINTERACTIVE) 'dwPriority

'This is a destination netword GUID
Dim Guid(3)
i=CLng(0)
res=ConnMgrMapURL("http://www.nsbasic.com/", Guid, i)
If res<>S_OK Then
  MsgBox "Error in ConnMapURL " & res
End If
'MsgBox guid(0) & vbCrLf & guid(1) & vbCrLf & guid(2) & vbCrLf & guid(3)

'Copy the result of ConnMgrMapUrl into the structure
For i=0 To 3
  ConnectionInfo(6+i)=CLng(guid(i))
Next
Connection=CLng(0)
timeout=CLng(60000) '60 seconds
status=CLng(0)
res=ConnMgrEstablishConnectionSync(ConnectionInfo, Connection, timeout, status)
MsgBox "res:" &  res & vbCrLf & "Connection:" & connection & vbCrLf & "Status: " & Hex(status)