Author Topic: Winsock functions with OxygenBasic  (Read 8439 times)

0 Members and 1 Guest are viewing this topic.

Charles Pegge

  • Guest
Re: Winsock functions with OxygenBasic
« Reply #15 on: July 31, 2015, 12:03:40 AM »
Hi Roland,

I got it working with RT32 and RTL64.

There is some strange corruption of the stack, which I have not been able to identify,  but creating a spill zone for the winsock calls of around 32 bytes (8 dwords) fixes the symptoms:

function connectHost(string host, int port)
   sys skt
   WSADATA wsa
   sockaddr_in server
  dword n[8] 'STACK SPILL !



Code: OxygenBasic
  1. 'Connect to a server, send and receive data
  2. 'the port and messages are specifically used for www.dict.org
  3.  
  4.  '% filename  "Dict_Send_Receive.exe"
  5.  % filename  "t.exe"
  6.   includepath "$/inc/"
  7.  'include     "RTL64.inc"
  8. 'include     "minwin.inc"
  9.  include     "console.inc"
  10.  
  11. % SOCKET_ERROR          = -1
  12. % SOCK_STREAM           = 1
  13. % AF_INET               = 2
  14. % INVALID_SOCKET        = 0xFFFFFFFF
  15. % INADDR_NONE           = 0xFFFFFFFF
  16. % WSAEWOULDBLOCK        = 10035
  17.  
  18.  
  19. type WSADATA 'Requires Windows Sockets 2.0
  20.  wVersion       as word          'WORD                      
  21.  wHighVersion   as word          'WORD                      
  22.  szDescription  as zString * 257 'char [WSADESCRIPTION_LEN+1]
  23.  szSystemStatus as zString * 129 'char [WSASYS_STATUS_LEN+1]  
  24.  iMaxSockets    as short         'unsigned short
  25.  iMaxUdpDg      as short         'unsigned short
  26.  lpVendorInfo   as sys           'char far*
  27. end type
  28.  
  29. 'in_addr structure
  30. type s_un_byte
  31.    s_b1 as byte
  32.    s_b2 as byte
  33.    s_b3 as byte
  34.    s_b4 as byte
  35. end type
  36.  
  37. type s_un_word
  38.    s_w1 as short
  39.    s_w2 as short
  40. end type
  41.    
  42. type in_addr
  43.   union 's_un
  44.    s_un_b as s_un_byte
  45.     s_un_w as s_un_word
  46.     s_addr as dword
  47.   end union
  48. end type
  49.  
  50. type sockaddr
  51.     sa_family as short   ' address family, AF_xxx
  52.    sa_data[14] as char  ' 14 bytes of protocol address};
  53. end type
  54.  
  55. ' IPv4 AF_INET sockets:
  56. type sockaddr_in
  57.     sin_family as short   ' e.g. AF_INET, AF_INET6
  58.    sin_port as short     ' e.g. htons(80)
  59.    sin_addr as in_addr   ' see struct in_addr, below
  60.    sin_zero[8] as char   ' zero this if you want to
  61. end type
  62.  
  63. type hostent
  64.    char   *h_name
  65.    sys     h_aliases   'char**
  66.   short   h_addrtype
  67.    short   h_length
  68.    sys     h_addr_list 'char**
  69. end type
  70.  
  71. 'FBIONBIO
  72. #define IOCPARM_MASK    0x7f     // Parameters must be < 128 bytes
  73. #define IOC_IN    0x80000000     // Copy in parameters
  74. #define _IOW(x,y,t)     (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
  75. #define FIONBIO _IOW('f', 126, unsigned long)
  76.  
  77. #define FIONBIO 0x80000000 or (4<<16) or (102<<8) or 126
  78.  
  79.  
  80. 'SELECTED PROCEDURES
  81. ====================
  82.  
  83. extern lib "ws2_32.dll"
  84.  
  85. ! WSAStartup (word wVersionRequested, WSADATA *lpWSAData) as int
  86. ! WSAGetLastError () as int
  87. ! socket(int af, int type, int protocol) as int
  88. ! closesocket(int s) as int
  89. ! WSACleanup () as int
  90. ! inet_addr (char *cp) as long 'cp: NULL-terminated character string for a number using ".'' (dotted) notation.
  91. ! htons(short hostshort) as short 'returns the value in TCP/IP network byte order
  92. ! connect(sys hSocket, sys name, int namelen) as int 'returns zero if no error
  93. ! send(sys s, char *buf, int len, int flags) as int
  94. ! recv(sys s, char *buf, int len, int flags) as int
  95. ! gethostbyname(char *name) as sys  ' ptr to struct hostent
  96. ! inet_ntoa(in_addr in) as char *
  97. ! ioctlsocket(sys s, long cmd, sys *argp) as int
  98.  
  99. end extern
  100.  
  101. ! Sleep lib "kernel32.dll" (dword dwMilliseconds)
  102.  
  103. 'Helper functions
  104. =================
  105.  
  106. sub endSocket(sys skt)
  107.    closesocket(skt)
  108.    WSACleanup()
  109.    print "Socket closed" & cr      
  110. end sub
  111.  
  112. function findAddress(string host)
  113.    string ip_addr
  114.    sys pHE
  115.    sys address
  116.    
  117.    'try dotted IP address
  118.   address = inet_addr(host)
  119.    if address = INADDR_NONE then
  120.      'no dotted IP address, try DNS
  121.     print "Calling gethostbyname with "  host " waiting ..." & cr
  122.      pHE = gethostbyname(host)
  123.      if pHE = NULL then
  124.         print "gethostbyname failed Error: "  WSAGetLastError() & cr
  125.         return INADDR_NONE
  126.      end if
  127.      hostent remoteHost at pHE  
  128.      sys *ad = remoteHost.h_addr_list
  129.      'only try first address
  130.     if ad then
  131.        ip_addr = inet_ntoa(byval *ad)
  132.        address=inet_addr(ip_addr)
  133.        if address = INADDR_NONE then
  134.           print "gethostbyname failed Error: "  WSAGetLastError() & cr
  135.           return INADDR_NONE
  136.        end if      
  137.      else
  138.        print "failed ..."
  139.        return INADDR_NONE
  140.      end if
  141.    end if
  142.      
  143.    return address            
  144. end function
  145.  
  146.  
  147. function connectHost(string host, int port)
  148.    sys skt
  149.    WSADATA wsa
  150.    sockaddr_in server
  151.    dword n[8] 'STACK SPILL !
  152.  
  153.    print cr & "Initialising Winsock..." & cr
  154.    
  155.    if WSAStartup(0x0202, wsa) then    
  156.       print "Initialising Socket failed. Error Code : " WSAGetLastError() & cr        
  157.       exit sub    
  158.    end if        
  159.  
  160.    print "Initialised." & cr
  161.  
  162.    ' Create a TCP socket
  163.   skt = socket(AF_INET , SOCK_STREAM , 0 )  
  164.  
  165.    if skt = INVALID_SOCKET then    
  166.       print "Could not create socket. Error: "   WSAGetLastError() & cr
  167.       exit sub    
  168.    end if    
  169.    print "Socket created: " & hex(skt) cr
  170.    
  171.    server.sin_addr.s_addr = findAddress(host)
  172.    server.sin_family = AF_INET;
  173.    server.sin_port = htons(port)
  174.    '
  175.   print "Server Address: " hex(server.sin_addr.s_addr) & cr
  176.    print "Server Family:  " hex(server.sin_family) & cr
  177.    print "Server Port:    " hex(server.sin_port) " (" hex(port) ")" & cr
  178.    '
  179.   'Connect to remote server
  180.   if connect(skt , &server , sizeof(server))<0 then  
  181.       print "Connect error: " & hex(WSAGetLastError()) & cr
  182.       endSocket(skt)
  183.       skt=-1          
  184.    end if
  185.          
  186.    return skt
  187.  
  188. end function
  189.  
  190.  
  191. function sendData (sys s, string message)
  192.    string msg = message & chr(13) & chr(10)
  193.    
  194.    result = send(s , msg , len(msg) , 0)
  195.    if result < 0 then
  196.       print result & ": Send failed" & cr
  197.       endSocket(s)
  198.    end if              
  199.    return result
  200. end function
  201.  
  202. function receiveData(sys s) as string
  203.    string serv_reply=""
  204.    string buffer = ""
  205.    int length=1024
  206.    int recv_size
  207.    
  208.    unsigned long iMode=1 '0=blocking mode, 1=nonblocking mode
  209.   int iResult = ioctlsocket(s, FIONBIO, &iMode)
  210.    if iResult != 0 then
  211.      print "ioctlsocket failed with error: " iResult & cr
  212.      endSocket(s)
  213.      exit sub
  214.    end if
  215.    
  216.    while 1
  217.       serv_reply = nuls length  
  218.       recv_size = recv(s , serv_reply , length , 0)    
  219.  
  220.       if recv_size  = SOCKET_ERROR then
  221.          err = WSAGetLastError()
  222.          if err = WSAEWOULDBLOCK then Sleep(1000): continue while    
  223.          print "recv failed" & cr
  224.          serv_reply = "ERROR"
  225.          endSocket(s)          
  226.       else        
  227.          buffer &= left(serv_reply, recv_size)
  228.       end if
  229.       if recv_size < length then exit while
  230.    wend
  231.    
  232.    return buffer
  233. end sub
  234.  
  235.  
  236. sub main()
  237.  
  238.    sys skt
  239.    string s_reply
  240.  
  241.    string host_name = "www.dict.org" '216.18.20.172
  242.   'string host_name = "dict1.us.dict.org"  '216.18.20.172
  243.   'string host_name = "216.18.20.172"
  244.            
  245.    skt = connectHost(host_Name, 2628)
  246.    if skt < 0 then exit sub
  247.    print "Connected" & cr & cr
  248.  
  249.    'Send some data    
  250.   print "Data Send (SHOW DB)" & cr
  251.    result = sendData(skt ,"SHOW DB")    
  252.    if result < 0 then exit sub            
  253.  
  254.    'Receive a reply from the server
  255.   s_reply = receiveData(skt)
  256.    print s_reply
  257.    print cr  
  258.    
  259.    print "Send QUIT message" & cr
  260.  
  261.    result = sendData(skt , "QUIT")
  262.    if result < 0 then exit sub
  263.  
  264.    s_reply = receiveData(skt)
  265.    print s_reply
  266.    print cr
  267.  
  268.    'close
  269.   endSocket(skt)
  270.  
  271. end sub
  272.  
  273. main()
  274.  
  275.  
  276. printl "Enter ..." : waitkey()
  277.  

Arnold

  • Guest
Re: Winsock functions with OxygenBasic
« Reply #16 on: August 19, 2015, 03:41:26 AM »
Hi Charles,

please excuse my very delayed response. There were some unexpected problems to solve and I was not able to concentrate on anything else. Moreover I had to look for and buy a new car because my old one was about to run down. And the last days I was a little bit lazy.

I would like to do another small experiment with winsock functions.(although the use is very limited)). And I would like to add some client functionality to the thesaurus projcect like John did. I hopefully will manage to achieve this aim until the end of the week.

Roland

Charles Pegge

  • Guest
Re: Winsock functions with OxygenBasic
« Reply #17 on: August 20, 2015, 01:17:01 AM »
Hi Roland,

I sense this is a good time to have a break from computing, and take advantage of fine weather and sunshine when it comes your way :)