Am I having a UNICODE issue?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Am I having a UNICODE issue?

Post by Rook Zimbabwe »

OK here is a simple Client / Server program Set.

If both are compiled in ASCII and by that I mean WITHOUT the flag for CREATE UNICODE EXECUTABLE being set in compiler options... it works well.

BUT

If I set the CLIENT to CREATE UNICODE EXECUTABLE and not the server... The server shows the program is there, but when it returns strings to the CLIENT nothing gets shown! Nothing is recieved by the client?

It is WORSE if BOTH are compiled with the UNICODE option!

So WHY?

CLIENT CODE

Code: Select all


Enumeration
  #Window_0
EndEnumeration

Enumeration
  #String_INPUT
  #Button_PLINKSERVER
  #String_SERVERADDRESS
  #Button_SEND
  #Button_GETNUM
  #Listview_CLIENT
EndEnumeration

Structure VisualDesignerGadgets
  Gadget.l
  EventFunction.l
EndStructure

Global ConnectionID
Global NewList EventProcedures.VisualDesignerGadgets()
Global *buffer = AllocateMemory(2000) ; to send and recieve info from DB

Procedure String_INPUT_Event(Window, Event, Gadget, Type)
  ; Debug "#String_INPUT"
EndProcedure

Procedure Button_PLINKSERVER_Event(Window, Event, Gadget, Type)
  Debug "#Button_PLINKSERVER"
  
EndProcedure

Procedure String_SERVERADDRESS_Event(Window, Event, Gadget, Type)
  ; Debug "#String_SERVERADDRESS"
EndProcedure

Procedure Button_SEND_Event(Window, Event, Gadget, Type)
  Debug "#Button_SEND"
    txt$ = GetGadgetText(#String_INPUT)
    If txt$ > ""
        query$ = "TXTSET"+txt$
         SendNetworkString(ConnectionID, query$)
    Else
        MessageRequester("PEBKC Error", "Please INPUT more then 2 characters..."+Chr(10)+"Then press [SEND]")
   EndIf
   
EndProcedure

Procedure Button_GETNUM_Event(Window, Event, Gadget, Type)
  Debug "#Button_GETNUM"
  big$ = GetGadgetText(#String_INPUT)
    If big$ > ""
        query$ = "GETNUM"+big$
         SendNetworkString(ConnectionID, query$)
    Else
        MessageRequester("PEBKC Error", "Please INPUT a Maximum Value for your Random Number..."+Chr(10)+"Then press [GET NUMBER]")
    EndIf
    
EndProcedure

Procedure Listview_CLIENT_Event(Window, Event, Gadget, Type)
  Debug "#Listview_CLIENT"
EndProcedure

Procedure RegisterGadgetEvent(Gadget, *Function)
  
  If IsGadget(Gadget)
    AddElement(EventProcedures())
    EventProcedures()\Gadget        = Gadget
    EventProcedures()\EventFunction = *Function
  EndIf
  
EndProcedure

Procedure CallEventFunction(Window, Event, Gadget, Type)
  
  ForEach EventProcedures()
    If EventProcedures()\Gadget = Gadget
      CallFunctionFast(EventProcedures()\EventFunction, Window, Event, Gadget, Type)
      LastElement(EventProcedures())
    EndIf
  Next
  
EndProcedure

Procedure Open_Window_0()
  
  If OpenWindow(#Window_0, 50, 41, 400, 264, "5n4r3 <l13nT3.14159",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
    If CreateGadgetList(WindowID(#Window_0))
      ListViewGadget(#Listview_CLIENT, 5, 10, 390, 135)
      RegisterGadgetEvent(#Listview_CLIENT, @Listview_CLIENT_Event())
      ButtonGadget(#Button_GETNUM, 5, 175, 195, 40, "GET RANDOM NUMBER")
      RegisterGadgetEvent(#Button_GETNUM, @Button_GETNUM_Event())
      ButtonGadget(#Button_SEND, 205, 175, 185, 40, "SEND LINE")
      RegisterGadgetEvent(#Button_SEND, @Button_SEND_Event())
      StringGadget(#String_SERVERADDRESS, 205, 225, 185, 25, "")
      RegisterGadgetEvent(#String_SERVERADDRESS, @String_SERVERADDRESS_Event())
      ButtonGadget(#Button_PLINKSERVER, 5, 225, 190, 25, "PLINK SERVER")
      RegisterGadgetEvent(#Button_PLINKSERVER, @Button_PLINKSERVER_Event())
      StringGadget(#String_INPUT, 5, 150, 385, 20, "")
      RegisterGadgetEvent(#String_INPUT, @String_INPUT_Event())
      
    EndIf
  EndIf
EndProcedure

Open_Window_0()

; ***************************************
; Change this for the address in your Server before you run this program
Server$ = "192.168.1.2"
; ***************************************

If InitNetwork() = 0
    Debug " NO NETWORK"
    MessageRequester("NETWORK ERROR", "NO NETWORK DETECTED"+Chr(10)+"Please verify Network Connection!"+Chr(10))
EndIf

AddGadgetItem(#ListView_CLIENT, -1,"NETWORK FOUND")

If ExamineIPAddresses()
    IP.l = NextIPAddress()
EndIf

PI$ = Str(IP.l)
PI$ = Right(PI$,5)

ip$ = Server$

ConnectionID = OpenNetworkConnection(ip$, 6654)
If ConnectionID = 0
    MessageRequester("NO SERVER", "NO SERVER DETECTED"+Chr(10)+Chr(10)+"Please verify Server Address"+Chr(10)+"and run resQ1.exe to change."+Chr(10)+Chr(10)+"Server IP:  "+server$+Chr(10)+Chr(10)+"Click OK To End program.")
    ip$ = "MANAGER"
    Goto Zoey
EndIf

Repeat
  
  Event  = WaitWindowEvent(12)
  Gadget = EventGadget()
  Type   = EventType()
  Window = EventWindow()
  
  Select Event
    Case #PB_Event_Gadget
      CallEventFunction(Window, Event, Gadget, Type)
      
  EndSelect
      If NetworkClientEvent(ConnectionID)
        length.l = ReceiveNetworkData(ConnectionID, *buffer, 4800)
        Str$ = PeekS(*buffer,4800)  ; , #PB_Ascii)
        Debug "recvd: "+str$
        t$ = Left(Str$,6)
        length = Len(Str$)
        Select t$
            Case "SETNUM"
                long = length - 6
                Sr$ = Right(Str$,long)
                AddGadgetItem(#ListView_CLIENT, -1, "RCVD: "+Sr$)
            Case "TXTSET"
                long = length - 6
                Sr$ = Right(Str$,long)
                AddGadgetItem(#ListView_CLIENT, -1, ":DVCR "+Sr$)
             ;   clearmemory()
        EndSelect        
       ; ClearMemory()
    EndIf
Until Event = #PB_Event_CloseWindow

Zoey:

End

and

SERVER CODE

Code: Select all

; (c) Copyright 2007 - Ralph Wm Dunn and Blue Mesa Software
; All Notional and International Rights Reserved for Perpetuity
Enumeration
    #Window_0
EndEnumeration

Enumeration
    #String_INPUT
    #Button_SEND
    #Text_1
    #Text_SERVADDRESS
    #Listview_TEXT
    #Listview_ACTIVITY
    #Server
    #Font1
EndEnumeration

Structure VisualDesignerGadgets
    Gadget.l
    EventFunction.l
EndStructure

Global ClientID
Global NewList EventProcedures.VisualDesignerGadgets()
Global FontID1
FontID1 = LoadFont(#Font1, "Courier", 9)
Global String$
Global buffet
Global query$

Global *bufferS = AllocateMemory(4800)

Declare ClearMemory(*memory.b, length.l)

Procedure GetNumber(MAX, ClientID)
    ReturnNumber = Random(MAX)
    goof$ = "SETNUM"+Str(ReturnNumber)
        SendNetworkString(ClientID, goof$)
    AddGadgetItem(#Listview_ACTIVITY, -1, "SENT: "+goof$)
EndProcedure

Procedure SwitchText(DOIT$,ClientID)
    blab = Len(DOIT$)
    For X = blab To 1 Step -1
        jok$ = Mid(DOIT$,X,1)
        joker$ = joker$ + jok$
    Next
    SendNetworkString(ClientID, "TXTSET"+joker$)
    AddGadgetItem(#Listview_ACTIVITY, -1, "SENT: "+joker$)
EndProcedure

Procedure UpdateList()
    
    Result = CountGadgetItems(#Listview_TEXT)
    SetGadgetItemState(#Listview_TEXT,Result,#PB_ListIcon_Selected)
    
    Result1 = CountGadgetItems(#Listview_ACTIVITY)
    SetGadgetItemState(#Listview_ACTIVITY,Result1+1,#PB_ListIcon_Selected)
    
EndProcedure

Procedure ClearMemory(buf,size) ; from tinman
    
    fillmemory_(*bufferS , 4799 , 0)
    
EndProcedure

Procedure String_INPUT_Event(Window, Event, Gadget, Type)
    Debug "#String_INPUT"
EndProcedure

Procedure Button_SEND_Event(Window, Event, Gadget, Type)
    String$ = GetGadgetText(#String_INPUT) ; to enter something to send
    SendNetworkData(ClientID, @String$, Len(String$))
    SetGadgetText(#String_INPUT, "") ; clear the text from memory
    AddGadgetItem(#Listview_TEXT, -1,"YOU: "+String$) ; throw the text in the window
    String$ = ""
    SetActiveGadget(#String_INPUT) ; reset the input string
    ClearMemory(*bufferS,48000)
    
EndProcedure

Procedure Text_SERVADDRESS_Event(Window, Event, Gadget, Type)
    Debug "#Text_SERVADDRESS"
EndProcedure

Procedure Listview_TEXT_Event(Window, Event, Gadget, Type)
    Result = GetGadgetState(#Listview_TEXT)
    msg$ = GetGadgetItemText(#ListView_TEXT, Result)
    MessageRequester("WHATSIT", msg$)
EndProcedure

Procedure Listview_ACTIVITY_Event(Window, Event, Gadget, Type)
    Result = GetGadgetState(#Listview_ACTIVITY)
    msg$ = GetGadgetItemText(#ListView_ACTIVITY, Result)
    MessageRequester("WHATSIT", msg$)
EndProcedure

Procedure RegisterGadgetEvent(Gadget, *Function)
    
    If IsGadget(Gadget)
        AddElement(EventProcedures())
        EventProcedures()\Gadget        = Gadget
        EventProcedures()\EventFunction = *Function
    EndIf
    
EndProcedure

Procedure CallEventFunction(Window, Event, Gadget, Type)
    
    ForEach EventProcedures()
        If EventProcedures()\Gadget = Gadget
            CallFunctionFast(EventProcedures()\EventFunction, Window, Event, Gadget, Type)
            LastElement(EventProcedures())
        EndIf
    Next
    
EndProcedure

Procedure Open_Window_0()
    
    If OpenWindow(#Window_0, 99, 332, 510, 380, "Sn4r3 53r\/3R .0999",  #PB_Window_TitleBar | #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
        If CreateGadgetList(WindowID(#Window_0))
            ListViewGadget(#Listview_ACTIVITY, 324, 42, 174, 246)
            SetGadgetFont(#Listview_ACTIVITY, FontID1)
            RegisterGadgetEvent(#Listview_ACTIVITY, @Listview_ACTIVITY_Event())
            ListViewGadget(#Listview_TEXT, 6, 42, 312, 246)
            RegisterGadgetEvent(#Listview_TEXT, @Listview_TEXT_Event())
            
            TextGadget(#Text_SERVADDRESS, 130, 12, 80, 18, "0.0.0.0", #PB_Text_Center) ; 6, 12, 120, 18
            RegisterGadgetEvent(#Text_SERVADDRESS, @Text_SERVADDRESS_Event())
            TextGadget(#Text_1, 20, 12, 120, 18, "SERVER ADDRESS ::") ; 132, 12, 132, 18
            ButtonGadget(#Button_SEND, 6, 336, 312, 36, "SEND")
            RegisterGadgetEvent(#Button_SEND, @Button_SEND_Event())
            StringGadget(#String_INPUT, 6, 294, 312, 42, "")
            RegisterGadgetEvent(#String_INPUT, @String_INPUT_Event())
            
        EndIf
    EndIf
EndProcedure

Open_Window_0()

;**********
InitNetwork()
If ExamineIPAddresses()
    IP.l = NextIPAddress()
EndIf

CreateNetworkServer(#Server, 6654)

AddGadgetItem(#Listview_ACTIVITY,-1,"Server Online") ;  Listening on IP (" + IPString(IP) + ")")
AddGadgetItem(#Listview_ACTIVITY,-1,"IP: (" + IPString(IP) + ")")
SetGadgetText(#Text_SERVADDRESS, ""+IPString(IP))
SetActiveGadget(#String_INPUT) ; reset the input string

Repeat

Event  = WaitWindowEvent(22)
Gadget = EventGadget()
Type   = EventType()
Window = EventWindow()

Select Event
Case #PB_Event_Gadget
CallEventFunction(Window, Event, Gadget, Type)
EndSelect

If NetworkServerEvent() = 1
    AddGadgetItem(#Listview_ACTIVITY,-1,"A new connection")
    ClientID.l = EventClient()
    IP = GetClientIP(ClientID)
    Cl$ = Str(IP)
    AddGadgetItem(#Listview_ACTIVITY,-1,"CLIENT: "+Cl$)
EndIf
If NetworkServerEvent() = 2
    ClearMemory(*bufferS,48000)
    length.l = ReceiveNetworkData(ClientID, *bufferS, 48000)
    String$ = PeekS(*bufferS, 48000)
    AddGadgetItem(#Listview_TEXT, -1,"INQ: "+String$)
    UpdateList()
    boogie = Len(String$)
    DOIT$ = Right(String$,boogie-6)
    command$ = Left(String$,6)
    
        Select command$
            Case "GETNUM" ; gets next ticket number
                MAX = Val(DOIT$)
                getnumber(MAX,ClientID)
                UpdateList()
                ClearMemory(*bufferS,48000)
            Case "TXTSET"
                SwitchText(DOIT$, ClientID)
        EndSelect

EndIf

Until Event = #PB_Event_CloseWindow

Zork:

End

I have a problem... My POS program has become popular in several Asian countries... they use UNICODE to enter Menu Items...
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

My guess is that the use of peeks() on a buffer of unicode characters is failing real quick due to the null's.

Run this, with and without unicode enabled, to see what I mean.

Code: Select all

a$="test"
l=Len(a$)*SizeOf(character)
*m=AllocateMemory(l+2)
PokeS(*m,a$)
For n=0 To l-1
Debug PeekB(*m+n)
next
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I think that's a good guess. Rook, SendNetworkString() does not send a terminating null - could this be your problem in that, in unicode, things are locking up whilst a double null is searched for etc?
I may look like a mule, but I'm not a complete ass.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

I see what you mean... one gives me 4 numbers... and WITH unicode I get four numbers and 4 0's alternating...

SO Unicode sends a terminating 0?

But would that NOT still send something to the CLIENT? I mean it shows NOthing recived... even stuff it doesn't understand!

How can I work around this?

Do I have to add a #NULL to the end of the string sent to the CLIENT?
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

I think you are going to have to work towards having both the client and server compiled using unicode for starters.

I think you'll need to work around using peeks().
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

Unicode :P Me now HATE unicode!
I think you'll need to work around using peeks()


{sigh} Yep I agree with that... I am probably gonna have to get the size of the buffer and then SCAN the whole size from 0 to ... and parse out what is there...

HEY it works with the SERVER as ASCII and the Client as UNi IF you change line 151 to:

Code: Select all

 Str$ = PeekS(*buffer,4800, #PB_Ascii) 
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Yes, either send the number of characters before the string so that the receiving server can then use PeekS() with the 'length' parameter set accordingly to read the string, or, place the string into a buffer, add the 2 trailing nulls (PokeS() will do this automatically) and then use SendNetworkData.
I may look like a mule, but I'm not a complete ass.
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Rook Zimbabwe wrote:Unicode :P Me now HATE unicode!
You're not alone there, I never use unicode!
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I never use ascii myself; unicode all the way! :wink:
I may look like a mule, but I'm not a complete ass.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

Well if I use the #PB_Ascii in my program (the unicode version...) I get INVALID MEMORY ACCESS...

but it does work in the Client/Server? Oh heck... I have been beating my brain against this all day... I quit.

Time for ST:Voyager and then to cook dinner! :D

If anyone has any ideas, please let me know!
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Rook Zimbabwe wrote:Time for ST:Voyager and then to cook dinner! :D

If anyone has any ideas, please let me know!
Well, seeing as you're a Texan I'd suggest a steak with chips, maybe some peas and definately gravy! :lol: :lol: :lol:
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

OK first things first...

A: You know what I meant! :P

B: No one in Texas over the age of 12 can be forced to eat peas... It is state law!

C: (back on topic) How come when I check unicode flag for both and run I see Asian character recieved by the server?
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

if you are reading ascii as unicode then the doublebyte values will be high, up into the CJK range so you would see asian chars.

can't say more just yet as I'm not at home with my compiler.
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Here is how to send and recieve an arbitrary-length string in unicode mode:

Code: Select all

; Server

Procedure.s ReceiveNetworkString()
  #BufferSize = 1024
  Protected Buffer = AllocateMemory(#BufferSize)
  Protected Result.s
  Repeat
    Bytes = ReceiveNetworkData(EventClient(), Buffer, #BufferSize)
    If Bytes > 0
      Result + PeekS(Buffer, Bytes)
    EndIf
  Until Bytes <> #BufferSize
  FreeMemory(Buffer)
  ProcedureReturn Result
EndProcedure

InitNetwork()

OpenWindow(0, 100, 100, 100, 100, "Server", #PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))

Connection = CreateNetworkServer(0, 999)

Repeat
  
  Event  = WaitWindowEvent(12)
  Gadget = EventGadget()
  Type   = EventType()
  Window = EventWindow()
  
  N = NetworkServerEvent()
  Select N
    Case #PB_NetworkEvent_Connect
      Debug "SERVER: client connected"
    Case #PB_NetworkEvent_Data
      Debug "SERVER: receive: " + ReceiveNetworkString()
  EndSelect
Until Event = #PB_Event_CloseWindow


Code: Select all

; Client

InitNetwork()
Connection = OpenNetworkConnection("127.0.0.1", 999)

Debug SendNetworkString(Connection, "Any string can go here, #¤%&/(")

; if I leave this out the string isn't sent correctly for some reason.
Repeat
  NetworkClientEvent(Connection)

ForEver
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Yes, that is better!

However, with your server code Trond, ReceiveNetworkData() returns the number of bytes, whilst PeekS() expects length to be in characters. Must admit that I am not very experienced with Network code so I could be seeing a problem which isn't there! :)
I may look like a mule, but I'm not a complete ass.
Post Reply