Author Topic: O2 Online Dictionary  (Read 3316 times)

0 Members and 1 Guest are viewing this topic.

JRS

  • Guest
O2 Online Dictionary
« on: October 15, 2018, 06:05:06 PM »
I wonder if sockets work?  :-X

It would be great to see if O2 is far along enough to reproduce the Online Dictionary example I have been using as my GUI Hello World.

Now that I have the Online Dictionary UI in a VB6 OCX DLL, I was thinking of finishing it by taking advantage of the features the service provides. (mostly formatting)

Thanks Charles!

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.      
  278.  
« Last Edit: October 15, 2018, 10:57:21 PM by John »

Charles Pegge

  • Guest
Re: O2 Online Dictionary
« Reply #1 on: October 16, 2018, 02:10:25 AM »
These are Roland's work :)

examples\System\WinSock\Dict_Send_Receive.o2bas

examples\System\WinSock\GetHostname.o2bas

JRS

  • Guest
Re: O2 Online Dictionary
« Reply #2 on: October 16, 2018, 09:19:08 AM »
These are Roland's work :)

examples\System\WinSock\Dict_Send_Receive.o2bas

examples\System\WinSock\GetHostname.o2bas

Thanks Roland!

Would you be able to merge what you have going with O2 Ui and this dict.org socket example to create a GUI Online Dictionary example for O2? The one being use in SB is an example but feel free to be creative and go you're own way.
« Last Edit: October 16, 2018, 09:36:32 AM by John »

Arnold

  • Guest
Re: O2 Online Dictionary
« Reply #3 on: October 16, 2018, 02:36:14 PM »
Hi John,

these are experimental functions which I would not have managed without Charles' help:
https://www.oxygenbasic.org/forum/index.php?topic=1354.msg14344#msg14344

I wanted to achieve something similar like your Online Dictionary realized with SB and Iup, but there were other interesting topics in the meantime too. Maybe I will try this next year again, now that Oxygenbasic has more options to do this without IUP. At the moment I would like to work on and finish some other small projects which I started. Of course, I hope that this can also be interesting for the use of Oxygenbasic.

Roland

JRS

  • Guest
Re: O2 Online Dictionary
« Reply #4 on: October 16, 2018, 02:55:27 PM »
I'm glad I was able to recycle one of your past efforts. I may take a shot at this as Charles already has IUP working in O2 using its C header(s).

This might be an alternative to IUP.

Win32++: A Simple Alternative to MFC.
« Last Edit: October 16, 2018, 09:28:39 PM by John »

Mike Lobanovsky

  • Guest
Re: O2 Online Dictionary
« Reply #5 on: October 17, 2018, 01:09:00 PM »
That Win32++ framework seems a no-nonsense thing and it entails a 3 times smaller payload than the standard MFC library.

It doesn't constrain the programmer to using OOP exclusively and allows unmanaged WinAPI to be used freely at the programmer's option. Yet it is utterly Windows specific and precludes code portability between platforms. This is what makes it somewhat less flexible than IUP.

It isn't that simple or compact but one can compile its parts selectively into one's programs thus reducing the payload still further depending on the program intended functionality and GUI.

JRS

  • Guest
Re: O2 Online Dictionary
« Reply #6 on: October 17, 2018, 02:25:27 PM »
The GCC compiler option is what got my attention.

I'm wondering if a DLLC dynamic FFI prototype might be worth doing to get a feel for its API.
« Last Edit: October 17, 2018, 02:44:59 PM by John »