Recv_() and send_() questions.
Recv_() and send_() questions.
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
Thanks
Re: Recv_() and send_() questions.
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.
Re: Recv_() and send_() questions.
maby mk-soft's network lib is the good choice for you.
viewtopic.php?f=12&t=73882
compiler option: thread safe
viewtopic.php?f=12&t=73882
compiler option: thread safe
poor English...
PureBasic & Delphi & VBA
PureBasic & Delphi & VBA
Re: Recv_() and send_() questions.
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!
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!
Re: Recv_() and send_() questions.
Did you use an UDP connection or a TCP connection?
Re: Recv_() and send_() questions.
I think it's just TCP, I just used InitNetwork() and OpenNetworkConnection().
Re: Recv_() and send_() questions.
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.
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.
Re: Recv_() and send_() questions.
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 helpTy1003 wrote:I think it's just TCP, I just used InitNetwork() and OpenNetworkConnection().
Re: Recv_() and send_() questions.
Please, at least, since you are not providing example code that shows your problem, provide an example of "mashed" data.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!
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.
Re: Recv_() and send_() questions.
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
And client
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 .
// Edit: Code tags were added and the code indentation was corrected (Kiffi)
Server
Code: Select all
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()
Code: Select all
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
// Edit: Code tags were added and the code indentation was corrected (Kiffi)
Re: Recv_() and send_() questions.
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
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 / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Recv_() and send_() questions.
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.
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.
Re: Recv_() and send_() questions.
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...
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...
Re: Recv_() and send_() questions.
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
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 / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
- RichAlgeni
- Addict
- Posts: 914
- Joined: Wed Sep 22, 2010 1:50 am
- Location: Bradenton, FL
Re: Recv_() and send_() questions.
Did you get your server to work correctly Ty1003?