It is currently Wed Jan 27, 2021 2:38 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: Recv_() and send_() questions.
PostPosted: Fri Oct 23, 2020 4:32 am 
Offline
User
User

Joined: Thu May 14, 2020 10:31 pm
Posts: 31
So I have an application that uses networking, E.G., initNetwork(), NetworkServerEvent() etc etc. However, I am having issues with Packet mixing. E.G., if two packets are sent at the same time, the text get scrambled together. I tried to solve it with a delay but this makes it lag, for quite obvious reasons. I heard about recv_() and send_(), and tried to add them, but from the looks of it, I would have to rewrite my entire client/server to use these. Is this really the best rout? Is there another way on Windows to make packet mixing not happen?
Thanks


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Fri Oct 23, 2020 10:14 am 
Offline
Enthusiast
Enthusiast

Joined: Mon Nov 03, 2008 9:56 pm
Posts: 564
If i understand correctly, you are sending in multiple threads at the same time and you are using global buffer? To solve this, you must allocate local buffer for each thread or use mutex.


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Fri Oct 23, 2020 11:23 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Wed Dec 23, 2009 3:26 pm
Posts: 220
maby mk-soft's network lib is the good choice for you.
https://www.purebasic.fr/english/viewtopic.php?f=12&t=73882
compiler option: thread safe

_________________
poor English...

PureBasic & Delphi & VBA


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Fri Oct 23, 2020 2:16 pm 
Offline
User
User

Joined: Thu May 14, 2020 10:31 pm
Posts: 31
Okay,
Firstly, no, the issue is if more than one packet is sent at aaround the same time, the text from them gets mashed.
And second, I'll take a look at that lib.
Thanks all for the suggestions!


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Fri Oct 23, 2020 5:40 pm 
Offline
Enthusiast
Enthusiast

Joined: Mon Apr 10, 2017 6:17 pm
Posts: 403
Location: Germany
Did you use an UDP connection or a TCP connection?

_________________
webpage


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Fri Oct 23, 2020 8:22 pm 
Offline
User
User

Joined: Thu May 14, 2020 10:31 pm
Posts: 31
I think it's just TCP, I just used InitNetwork() and OpenNetworkConnection().


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Fri Oct 23, 2020 10:31 pm 
Offline
Always Here
Always Here

Joined: Sun Sep 07, 2008 12:45 pm
Posts: 5219
Location: Germany
This is a coding question.

So write a small (working) version of your code and show it in this section.
Something with your receive code is wrong.

Every packet come on its own and since the client is known, it can not mixed up.
(If it is handled correct). API functions changes nothing on the receive logic.


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Sat Oct 24, 2020 11:32 am 
Offline
Enthusiast
Enthusiast

Joined: Mon Apr 10, 2017 6:17 pm
Posts: 403
Location: Germany
Ty1003 wrote:
I think it's just TCP, I just used InitNetwork() and OpenNetworkConnection().


If you used OpenNetworkConnection, the default connection mode will be TCP. The order with TCP will be maintained, so the problem is in your code. Show your implementation, so we can help :)

_________________
webpage


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Sat Oct 24, 2020 2:11 pm 
Offline
Enthusiast
Enthusiast

Joined: Mon Nov 03, 2008 9:56 pm
Posts: 564
Ty1003 wrote:
Okay,
Firstly, no, the issue is if more than one packet is sent at aaround the same time, the text from them gets mashed.
And second, I'll take a look at that lib.
Thanks all for the suggestions!

Please, at least, since you are not providing example code that shows your problem, provide an example of "mashed" data.
For example, if you send 2 packets
packet1: "abcd"
packet2: "1234"

and you receive "abcd1234" in a single read but you want to receive each of them separately then you must add a header to each network packet that indicates its size if packets do not have fixed size. If all packets are fixed size then you can specify number of bytes to read when you receive them.


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Sat Oct 24, 2020 2:35 pm 
Offline
User
User

Joined: Thu May 14, 2020 10:31 pm
Posts: 31
Alright, here are the networking parts of my code. I took out the gadget and sound playing bits, as I don't think they would effect it at all.

Server
Code:
Global NewMap Users.S()
#MSG_WAITALL=$8
Declare Main()
Procedure Main()
  OpenConsole("Talk Server.")
  InitNetwork()
  Protected Port=6832
  Delay(50)
  If CreateNetworkServer(0,Port)
    PrintN("Server created (Port "+Str(Port)+").")
    If ReadFile(0,"MOTD.txt")
      Protected MOTD.S=ReadString(0)
    EndIf
    Repeat
      Protected SEvent=NetworkServerEvent()
      If SEvent
        Protected ClientID=EventClient()
        Select SEvent
          Case #PB_NetworkEvent_Connect
            ID=ClientID
            PrintN(""+ID+" has connected !")
          Case #PB_NetworkEvent_Data
            *Buffer=AllocateMemory(1000)
            recv_(ClientID,*Buffer,1000,#MSG_WAITALL)
            ID=ClientID
            Protected PeekedMem.S=""
            PeekedMem=PeekS(*Buffer,-1,#PB_UTF8)
            Debug PeekedMem
            If Left(PeekedMem,1)="@"
              Protected Name.S=Mid(PeekedMem,2)
              Users(Str(ID))=Name
              Protected MOTDString.S="@MOTD "+MOTD
              send_(Val(MapKey(Users())),@MOTDString,StringByteLength(MOTDString),#Null)
              recv_(ID,*Buffer,1000,#MSG_WAITALL)
              Protected NameString.S=Name+" has connected"
              ForEach Users()
                send_(Val(MapKey(Users())),@NameString,StringByteLength(NameString),#Null)
              Next
            Else
              If FindMapElement(Users(),Str(ID))
                Protected Chat.S=Users()+": "+PeekedMem
                PrintN(Chat)
                ForEach Users()
                  send_(Val(MapKey(Users())),@Chat,StringByteLength(Chat),#Null)
                Next
              EndIf
            EndIf
            FreeMemory(*Buffer)
          Case #PB_NetworkEvent_Disconnect
            ID=ClientID
            PrintN(""+ID+" has disconnected !")
        EndSelect
      EndIf
    ForEver
    CloseNetworkServer(0)
  Else
    PrintN("Can't create the server (port in use ?).")
  EndIf
EndProcedure
Main()


And client
Code:
InitNetwork()
Protected Port=6832
Protected Name.S=InputRequester("Name","Please enter your name.","")
If Name=""
  End
EndIf
Protected ConnectionID=OpenNetworkConnection("127.0.0.1",Port)
If ConnectionID
  send_(ConnectionID,@Name,StringByteLength(Name),#Null)
  Protected TempName.S="@"+Name
  send_(ConnectionID, @TempName,StringByteLength(TempName),#Null)
  Repeat
    Protected SEvent=NetworkClientEvent(ConnectionID)
    Select SEvent
      Case #PB_NetworkEvent_Disconnect
        ConnectionID=0
        PlaySound(Disconnect)
        Break
      Case #PB_NetworkEvent_Data
        If ConnectionID=0
          Break
        EndIf
        Protected *Buffer=AllocateMemory(1000)
        recv_(ConnectionID,*Buffer,1000,#MSG_WAITALL)
        Protected Message.S=PeekS(*Buffer,-1,#PB_UTF8)
        If FindString(Message,": ")=0
          If FindString(Message,"has connected")<>0
            PlaySound(Online)
          ElseIf Left(Message,5)="@MOTD"
            Message=Mid(Message,6)
          EndIf
        Else
          PlaySound(Chat)
        EndIf
        AddGadgetItem(#History_List,-1,Message)
        FreeMemory(*Buffer)
    EndSelect
    Protected Event=WaitWindowEvent(1)
    Select Event
      Case #PB_Event_Menu
        Select EventMenu()
          Case #Send
            If GetActiveGadget()=#Chat_Field
              Protected Content.S=GetGadgetText(#Chat_Field)
              If Content=""
                PlaySound(Empty)
                Continue
              Else
                SendNetworkString(ConnectionID,Content,#PB_UTF8)
                SetGadgetText(#Chat_Field,"")
                PlaySound(Send)
              EndIf
            EndIf
        EndSelect
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #Exit_Button
            CloseNetworkConnection(ConnectionID)
            End
        EndSelect
    EndSelect
  ForEver
EndIf


That is missing the gadget and sound loading/playing code, but you should be able to get the idea. The problem I was having was with mixing packets, and so I tried switching to send_() and recv_() from the WinAPI, but now nothing gets sent at all :D :D.

// Edit: Code tags were added and the code indentation was corrected (Kiffi)


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Sat Oct 24, 2020 6:39 pm 
Offline
Addict
Addict
User avatar

Joined: Fri May 12, 2006 6:51 pm
Posts: 2820
Location: Germany
TCP/IP only takes care of this with a handshake, which allows data up to 64 KB to be sent and received in packets in the correct order. ISO model layer 4.

This means that the data is transmitted piece by piece as packets (local network approx. 1500 byte, Internet a little less approx. 1492 byte)

Your data which is sent and received is in the ISO model layer 5 to 7 and you have to take care of the content yourself, you also have to take care of the protocols like http(s) FTP, etc.

SendNetworkData only enters the data for sending into the send buffer and ReceiveNetworkData only fetches the data already received into the receive buffer.

If all packets have arrived in the whole large (up to 64 kb), you have to check yourself, because it is possible that a part of the data has already arrived

This also means that if you call SendNetwork twice, all data will be available when the receive buffer is queried.

Common methods of transmitting data is to use a header (for example, Modbus/TCP),
Work with control characters (StartOfText #STX$, EndOfText #ETX$),
or
As with HTTP in Text Header to include the size of the data

_________________
My Projects ThreadToGUI / OOP-BaseClass / OOP-BaseClassDispatch / EventDesigner V3
PB v3.30 / v5.70 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Sat Oct 24, 2020 7:40 pm 
Offline
Enthusiast
Enthusiast

Joined: Mon Apr 10, 2017 6:17 pm
Posts: 403
Location: Germany
Why do you use a wild mix of purebasic network library and api calls?

That can create 'interesting' problems due to internal buffering. It could be interesting to trace what actually happens in such a case with wireshark and WinApiOverride. Basically the network api sequence might be different to what you think it is. Try using only the purebasic network functions first.

_________________
webpage


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Sat Oct 24, 2020 8:05 pm 
Offline
User
User

Joined: Thu May 14, 2020 10:31 pm
Posts: 31
Hi.
Initially, I did use just PB calls. But the MOTD and online packet, for example would get mashed. Or if two users sent a chat at the same time. So I tried using recv_() and send_() to insure the packet arrives before sending the next one, but it doesn't work... :(


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Sat Oct 24, 2020 9:01 pm 
Offline
Addict
Addict
User avatar

Joined: Fri May 12, 2006 6:51 pm
Posts: 2820
Location: Germany
Not read what I have written?

The same applies to API Send and Receive

Here an example with short text sending over UDP and control character STX, ETX
Link: viewtopic.php?f=12&t=74200

_________________
My Projects ThreadToGUI / OOP-BaseClass / OOP-BaseClassDispatch / EventDesigner V3
PB v3.30 / v5.70 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace


Top
 Profile  
Reply with quote  
 Post subject: Re: Recv_() and send_() questions.
PostPosted: Mon Nov 30, 2020 11:10 pm 
Offline
Addict
Addict
User avatar

Joined: Wed Sep 22, 2010 1:50 am
Posts: 811
Location: Bradenton, FL
Did you get your server to work correctly Ty1003?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye