'Connect to a server, send and receive data
'the port and messages are specifically used for www.dict.org
'% filename "Dict_Send_Receive.exe"
% filename "t.exe"
includepath "$/inc/"
'include "RTL64.inc"
'include "minwin.inc"
include "console.inc"
% SOCKET_ERROR = -1
% SOCK_STREAM = 1
% AF_INET = 2
% INVALID_SOCKET = 0xFFFFFFFF
% INADDR_NONE = 0xFFFFFFFF
% WSAEWOULDBLOCK = 10035
type WSADATA 'Requires Windows Sockets 2.0
wVersion as word 'WORD
wHighVersion as word 'WORD
szDescription as zString * 257 'char [WSADESCRIPTION_LEN+1]
szSystemStatus as zString * 129 'char [WSASYS_STATUS_LEN+1]
iMaxSockets as short 'unsigned short
iMaxUdpDg as short 'unsigned short
lpVendorInfo as sys 'char far*
end type
'in_addr structure
type s_un_byte
s_b1 as byte
s_b2 as byte
s_b3 as byte
s_b4 as byte
end type
type s_un_word
s_w1 as short
s_w2 as short
end type
type in_addr
union 's_un
s_un_b as s_un_byte
s_un_w as s_un_word
s_addr as dword
end union
end type
type sockaddr
sa_family as short ' address family, AF_xxx
sa_data[14] as char ' 14 bytes of protocol address};
end type
' IPv4 AF_INET sockets:
type sockaddr_in
sin_family as short ' e.g. AF_INET, AF_INET6
sin_port as short ' e.g. htons(80)
sin_addr as in_addr ' see struct in_addr, below
sin_zero[8] as char ' zero this if you want to
end type
type hostent
char *h_name
sys h_aliases 'char**
short h_addrtype
short h_length
sys h_addr_list 'char**
end type
'FBIONBIO
#define IOCPARM_MASK 0x7f // Parameters must be < 128 bytes
#define IOC_IN 0x80000000 // Copy in parameters
#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define FIONBIO _IOW('f', 126, unsigned long)
#define FIONBIO 0x80000000 or (4<<16) or (102<<8) or 126
'SELECTED PROCEDURES
====================
extern lib "ws2_32.dll"
! WSAStartup (word wVersionRequested, WSADATA *lpWSAData) as int
! WSAGetLastError () as int
! socket(int af, int type, int protocol) as int
! closesocket(int s) as int
! WSACleanup () as int
! inet_addr (char *cp) as long 'cp: NULL-terminated character string for a number using ".'' (dotted) notation.
! htons(short hostshort) as short 'returns the value in TCP/IP network byte order
! connect(sys hSocket, sys name, int namelen) as int 'returns zero if no error
! send(sys s, char *buf, int len, int flags) as int
! recv(sys s, char *buf, int len, int flags) as int
! gethostbyname(char *name) as sys ' ptr to struct hostent
! inet_ntoa(in_addr in) as char *
! ioctlsocket(sys s, long cmd, sys *argp) as int
end extern
! Sleep lib "kernel32.dll" (dword dwMilliseconds)
'Helper functions
=================
sub endSocket(sys skt)
closesocket(skt)
WSACleanup()
print "Socket closed" & cr
end sub
function findAddress(string host)
string ip_addr
sys pHE
sys address
'try dotted IP address
address = inet_addr(host)
if address = INADDR_NONE then
'no dotted IP address, try DNS
print "Calling gethostbyname with " host " waiting ..." & cr
pHE = gethostbyname(host)
if pHE = NULL then
print "gethostbyname failed Error: " WSAGetLastError() & cr
return INADDR_NONE
end if
hostent remoteHost at pHE
sys *ad = remoteHost.h_addr_list
'only try first address
if ad then
ip_addr = inet_ntoa(byval *ad)
address=inet_addr(ip_addr)
if address = INADDR_NONE then
print "gethostbyname failed Error: " WSAGetLastError() & cr
return INADDR_NONE
end if
else
print "failed ..."
return INADDR_NONE
end if
end if
return address
end function
function connectHost(string host, int port)
sys skt
WSADATA wsa
sockaddr_in server
dword n[8] 'STACK SPILL !
print cr & "Initialising Winsock..." & cr
if WSAStartup(0x0202, wsa) then
print "Initialising Socket failed. Error Code : " WSAGetLastError() & cr
exit sub
end if
print "Initialised." & cr
' Create a TCP socket
skt = socket(AF_INET , SOCK_STREAM , 0 )
if skt = INVALID_SOCKET then
print "Could not create socket. Error: " WSAGetLastError() & cr
exit sub
end if
print "Socket created: " & hex(skt) cr
server.sin_addr.s_addr = findAddress(host)
server.sin_family = AF_INET;
server.sin_port = htons(port)
'
print "Server Address: " hex(server.sin_addr.s_addr) & cr
print "Server Family: " hex(server.sin_family) & cr
print "Server Port: " hex(server.sin_port) " (" hex(port) ")" & cr
'
'Connect to remote server
if connect(skt , &server , sizeof(server))<0 then
print "Connect error: " & hex(WSAGetLastError()) & cr
endSocket(skt)
skt=-1
end if
return skt
end function
function sendData (sys s, string message)
string msg = message & chr(13) & chr(10)
result = send(s , msg , len(msg) , 0)
if result < 0 then
print result & ": Send failed" & cr
endSocket(s)
end if
return result
end function
function receiveData(sys s) as string
string serv_reply=""
string buffer = ""
int length=1024
int recv_size
unsigned long iMode=1 '0=blocking mode, 1=nonblocking mode
int iResult = ioctlsocket(s, FIONBIO, &iMode)
if iResult != 0 then
print "ioctlsocket failed with error: " iResult & cr
endSocket(s)
exit sub
end if
while 1
serv_reply = nuls length
recv_size = recv(s , serv_reply , length , 0)
if recv_size = SOCKET_ERROR then
err = WSAGetLastError()
if err = WSAEWOULDBLOCK then Sleep(1000): continue while
print "recv failed" & cr
serv_reply = "ERROR"
endSocket(s)
else
buffer &= left(serv_reply, recv_size)
end if
if recv_size < length then exit while
wend
return buffer
end sub
sub main()
sys skt
string s_reply
string host_name = "www.dict.org" '216.18.20.172
'string host_name = "dict1.us.dict.org" '216.18.20.172
'string host_name = "216.18.20.172"
skt = connectHost(host_Name, 2628)
if skt < 0 then exit sub
print "Connected" & cr & cr
'Send some data
print "Data Send (SHOW DB)" & cr
result = sendData(skt ,"SHOW DB")
if result < 0 then exit sub
'Receive a reply from the server
s_reply = receiveData(skt)
print s_reply
print cr
print "Send QUIT message" & cr
result = sendData(skt , "QUIT")
if result < 0 then exit sub
s_reply = receiveData(skt)
print s_reply
print cr
'close
endSocket(skt)
end sub
main()
printl "Enter ..." : waitkey()