udp networking in freebasic.
udp networking in freebasic.
For many years making multiplayer games has been an interest of mine. I've learned how to make a simple network in freebasic using tcp but it runs too slow for games. I've read that udp networking is the way to go for speed but I can't find any information on how to do this in freebasic.
My needs:
--more than 1 client
--be able to send a lot of information quickly for RTS and action games
This looks simple but it has no udp examples. Can I use this for games?
http://www.freebasic.net/forum/viewtopi ... =7&t=23421
My needs:
--more than 1 client
--be able to send a lot of information quickly for RTS and action games
This looks simple but it has no udp examples. Can I use this for games?
http://www.freebasic.net/forum/viewtopi ... =7&t=23421
Re: udp networking in freebasic.
Not sure if imple [N]etwork [C]onnection can be used with UDP.
In 2010 I played with UDP a little: http://www.freebasic.net/forum/viewtopi ... 6&start=14
In 2010 I played with UDP a little: http://www.freebasic.net/forum/viewtopi ... 6&start=14
Re: udp networking in freebasic.
I tested you program. Do you mind if I fool with it and use it in some of my programs?
I added visuals to test the speed and there seems to be some bad delay in messages sent from the server to a client. Client to server messages are instant though.
network.bi
server
client
I added visuals to test the speed and there seems to be some bad delay in messages sent from the server to a client. Client to server messages are instant though.
network.bi
Code: Select all
#define __FD_SETSIZE 32
#If Defined(__FB_WIN32__)
#Include Once "win/winsock2.bi"
#ElseIf Defined(__FB_LINUX__)
#Include Once "crt/netdb.bi"
#Include Once "crt/sys/socket.bi"
#Include Once "crt/netinet/in.bi"
#Include Once "crt/arpa/inet.bi"
#Include Once "crt/unistd.bi"
#Include Once "crt/sys/select.bi"
#Else
#Error Platform Not supported
#EndIf
function init_socket_API() as integer
#Ifdef __FB_WIN32__
dim as WSADATA wsaData
return WSAStartup(MAKEWORD(2,2), @wsaData)
#Else
return 0
#EndIf
end function
sub close_socket_API()
#Ifdef __FB_WIN32__
WSACleanup()
#Else
'Nothing to do
#EndIf
end sub
function inet_addr_rev(ipAddress as in_addr) as string
dim as ubyte ptr pChar = cptr(ubyte ptr, @ipAddress)
return str(pChar[0]) & _
"." & str(pChar[1]) & _
"." & str(pChar[2]) & _
"." & str(pChar[3])
end function
type net_data
as integer seqNr
as integer x
as integer y
end type
Code: Select all
Screen 18,32
Dim As Integer x,y,x2,y2
#include "network.bi"
#include "fbgfx.bi"
#DEFINE SERVER_PORT 27015
#DEFINE CLIENT_IP "192.168.1.18"
'--- SERVER ---
dim as SOCKET socketId
dim as sockaddr_in clientAddr
dim as sockaddr_in serverAddr
dim as integer serverAddrSize = sizeof(serverAddr)
dim as integer clientAddrSize = sizeof(clientAddr)
dim as integer iResult, sendCount
dim as net_data netDataIn
dim as net_data netDataOut
dim as fd_set readfds, readfds0
dim as fd_set writefds, writefds0
dim as timeval timeout
iResult = init_socket_API()
if (iResult <> 0) Then print "Winsock init: Error":Sleep:End
socketId = socket_(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
if (socketId < 0) then print "Socket: Error":close_socket_API():End
serverAddr.sin_family = AF_INET
serverAddr.sin_port = htons(SERVER_PORT)
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY)
iResult = bind(socketId, cptr(sockaddr ptr, @serverAddr), serverAddrSize)
if (iResult < 0) then print "Bind: Error":close_socket_API():Sleep:End
clientAddr.sin_family = AF_INET
clientAddr.sin_port = htons(SERVER_PORT)
clientAddr.sin_addr.s_addr = inet_addr(CLIENT_IP)
FD_ZERO(@readfds0)
FD_ZERO(@writefds0)
FD_SET_(socketId, @readfds0)
FD_SET_(SocketId, @writefds0)
Do
ScreenLock
Cls
Circle(x,y),10,RGB(255,255,255)
Circle(x2,y2),10,RGB(255,255,255)
ScreenUnLock
Sleep 1
If MultiKey(17) Then y2-=1
If MultiKey(31) Then y2+=1
If MultiKey(32) Then x2+=1
If MultiKey(30) Then x2-=1
'Keep a backup because SelectSocket will change the data
readfds = readfds0
writefds = writefds0
timeout = type(0, 0)
iResult = selectSocket(FD_SETSIZE, @readfds, @writefds, NULL, @timeout)
if (iResult = 0) then
print "SelectSocket: Timeout"
elseif (iResult < 0) then
print "SelectSocket: Error"
else
'print "SelectSocket: Sockets ready: "; iResult
end if
netDataOut.seqNr = sendCount
netDataOut.x = x2:netDataOut.y = y2'"Server says: No!"
if(FD_ISSET(socketId, @writefds)) then
iResult = sendto(socketId, cptr(ubyte ptr, @netDataOut), _
SizeOf(net_data), 0, cptr(sockaddr ptr, @clientAddr), clientAddrSize)
if (iResult < 0) then
print "Send: Error":closeSocket(socketId):close_socket_API():Sleep:End
else
print "Bytes send:"; iResult;
print " to: "; inet_addr_rev(clientAddr.sin_addr)
end if
end if
sendCount += 1
if(FD_ISSET(socketId, @readfds)) then
iResult = recvfrom(socketId, cptr(ubyte ptr, @netDataIn), _
sizeof(net_data), 0, cptr(sockaddr ptr, @clientAddr), @clientAddrSize)
if (iResult > 0) then
print "Bytes received:"; iResult;
Print " from: "; inet_addr_rev(clientAddr.sin_addr)
Print "SeqNr: "; netDataIn.seqNr;
print " text: "; netDataIn.x
x=netDataIn.x:y=netDataIn.y
elseif (iResult = 0) then
print "Receive: Connection closed":closesocket(socketId):close_socket_API():Sleep:End
else
print "Receive: Error":closesocket(socketId):close_socket_API():Sleep:End
end if
end if
Loop Until MultiKey(1)
iResult = closesocket(socketId)
if (iResult < 0) then
print "CloseSocket: Error"
end if
close_socket_API()
Code: Select all
Screen 18,32
Dim As Integer x,y,x2,y2
#Include "network.bi"
#include "fbgfx.bi"
#DEFINE SERVER_PORT 27015
#DEFINE SERVER_IP "192.168.1.11"
'--- CLIENT ---
dim as SOCKET socketId
dim as sockaddr_in serverAddr
dim as integer serverAddrSize = sizeof(serverAddr)
dim as integer iResult, sendCount
dim as fd_set readfds, readfds0
dim as fd_set writefds, writefds0
dim as timeval timeout
dim as net_data netDataIn
dim as net_data netDataOut
iResult = init_socket_API()
if (iResult <> 0) then
print "Winsock init: Error"
sleep
end
end if
socketId = socket_(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
if (socketId < 0) then
print "Socket: Error"
close_socket_API()
sleep
end
end if
serverAddr.sin_family = AF_INET
serverAddr.sin_port = htons(SERVER_PORT)
serverAddr.sin_addr.s_addr = inet_addr(SERVER_IP)
FD_ZERO(@readfds0)
FD_ZERO(@writefds0)
FD_SET_(socketId, @readfds0)
FD_SET_(SocketId, @writefds0)
Do
ScreenLock
Cls
Circle(x,y),10,RGB(255,255,255)
Circle(x2,y2),10,RGB(255,255,255)
ScreenUnLock
Sleep 1
If MultiKey(17) Then y-=1
If MultiKey(31) Then y+=1
If MultiKey(32) Then x+=1
If MultiKey(30) Then x-=1
'Keep a backup because SelectSocket will change the data
readfds = readfds0
writefds = writefds0
timeout = type(0, 0)
iResult = selectSocket(FD_SETSIZE, @readfds, @writefds, NULL, @timeout)
if (iResult = 0) then
print "SelectSocket: Timeout"
elseif (iResult < 0) then
print "SelectSocket: Error"
else
'print "SelectSocket: Sockets ready: "; iResult
end if
netDataOut.seqNr = sendCount
netDataOut.x=x:netDataOut.y=y'"Client says: Yes!"
if(FD_ISSET(socketId, @writefds)) then
print "Send: Trying..."
iResult = sendto(socketId, cptr(ubyte ptr, @netDataOut), _
sizeof(net_data), 0, cptr(sockaddr ptr, @serverAddr), serverAddrSize)
if (iResult < 0) then
print "Send: Error":CloseSocket(socketId):close_socket_API():sleep:end
else
Print "Bytes send:"; iResult;
print " to: "; inet_addr_rev(serverAddr.sin_addr)
end if
end if
sendCount += 1
if(FD_ISSET(socketId, @readfds)) then
print "Receive: Trying..."
iResult = recvfrom(socketId, cptr(ubyte ptr, @netDataIn), _
sizeof(net_data), 0, cptr(sockaddr ptr, @serverAddr), @serverAddrSize)
if (iResult > 0) then
Print "Bytes received:"; iResult;
Print " from: "; inet_addr_rev(serverAddr.sin_addr)
Print "SeqNr: "; netDataIn.seqNr;
print " text: "; netDataIn.x
x2=netDataIn.x:y2=netDataIn.y
elseif (iResult = 0) then
print "Receive: Connection closed":CloseSocket(socketId):close_socket_API():sleep:end
else
Print "Receive: Error":closesocket(socketId):close_socket_API():sleep:end
end if
end if
Loop Until MultiKey(1)
iResult = closeSocket(socketId)
if (iResult < 0) then
print "CloseSocket: Error"
end if
close_socket_API()
Re: udp networking in freebasic.
[duplicate]
Last edited by badidea on Apr 30, 2017 15:18, edited 1 time in total.
Re: udp networking in freebasic.
Not at all, please do fool around with it :-)Do you mind if I fool with it and use it in some of my programs?
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: udp networking in freebasic.
To day there is no need for using UDP packages anymore.
In the time of modems like 19K 56K or 115K baud it was OK.
Both on LAN and WAN the ping rate are the same for TCP and UDP packages.
The frame where the content of TCP packages are included are little bit larger than UDP
but TCP comes in in the same order at it was send and no packages will be lost.
For UDP packages you have collect them all and bring it in the right order
and if an UDP package are missing you have to send an extra message to the server.
"hello server one package with timestamp XYZ from client ABC are lost please send it again"
For short sorting the incomming UDP packages by a timestamp and ask for missing packages
will not be faster then using directly TCP packages.
I wrote the TCP plugin for Basic4GL and we have tested it with 32 clients per game session UDP was never really faster.
For all those reasons I don't put UDP in my cute Simple Network Connection include file.
There is one point where UDP is the first choice if you stream video and or audio content.
(The result of a missing UDP package while streaming is a cute cube with wrong colors on the screen but with 24 FPS you won't noticed this tiny error)
bla bla bla :-)
Joshy
In the time of modems like 19K 56K or 115K baud it was OK.
Both on LAN and WAN the ping rate are the same for TCP and UDP packages.
The frame where the content of TCP packages are included are little bit larger than UDP
but TCP comes in in the same order at it was send and no packages will be lost.
For UDP packages you have collect them all and bring it in the right order
and if an UDP package are missing you have to send an extra message to the server.
"hello server one package with timestamp XYZ from client ABC are lost please send it again"
For short sorting the incomming UDP packages by a timestamp and ask for missing packages
will not be faster then using directly TCP packages.
I wrote the TCP plugin for Basic4GL and we have tested it with 32 clients per game session UDP was never really faster.
For all those reasons I don't put UDP in my cute Simple Network Connection include file.
There is one point where UDP is the first choice if you stream video and or audio content.
(The result of a missing UDP package while streaming is a cute cube with wrong colors on the screen but with 24 FPS you won't noticed this tiny error)
bla bla bla :-)
Joshy
Re: udp networking in freebasic.
UDP is very useful for many things. For one it's a connectionless protocol. This makes it very nice to use for some things unlike TCP. For example simple data acquisition where the odd missed packet is no problem.
I really admire your work, joshy, but you're off the mark here saying UDP is outdated like a modem. UDP and TCP serve different, complementary and orthogonal purposes.
I really admire your work, joshy, but you're off the mark here saying UDP is outdated like a modem. UDP and TCP serve different, complementary and orthogonal purposes.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: udp networking in freebasic.
Ups this are toaly new for me ;-)caseih wrote:UDP is very useful for many things. For one it's a connectionless protocol. This makes it very nice to use for some things unlike TCP. For example simple data acquisition where the odd missed packet is no problem.
We are talking about UDP vs TCP packages for multiplayer games you know ?
Joshy
Re: udp networking in freebasic.
Pretty sure UDP still has a place in gaming communication. In any case, the OP said he found TCP/IP connections were too slow for him, likely due to the time it takes to build and tear down connections, and likely due to how he was using connections. I am guessing that many games implement their own light-weight connection protocols on top of UDP for various reasons including faster build/tear downs, better handling of dropped connections, NAT traversal, and other issues.
In fact, UDP's connectionless nature combined with how firewalls NAT UDP packets means that UDP can facilitate direct peer-to-peer communication through NATs and firewalls, whereas TCP/IP cannot. Once a UDP packet goes through the firewall and opens an outward facing UDP port, anyone can send packets to it. I'm sure many games rely on this feature of UDP.
In fact, UDP's connectionless nature combined with how firewalls NAT UDP packets means that UDP can facilitate direct peer-to-peer communication through NATs and firewalls, whereas TCP/IP cannot. Once a UDP packet goes through the firewall and opens an outward facing UDP port, anyone can send packets to it. I'm sure many games rely on this feature of UDP.
Re: udp networking in freebasic.
Where do you get network.bi from? Been looking for half an hour and still cant find it.
Re: udp networking in freebasic.
Ping is ICMP, so neither TCP or UDP.D.J.Peters wrote:To day there is no need for using UDP packages anymore.
In the time of modems like 19K 56K or 115K baud it was OK.
Both on LAN and WAN the ping rate are the same for TCP and UDP packages.
Afaik the TCP/IP handshake is quite slow (since it has to go back and forth 3 times).The frame where the content of TCP packages are included are little bit larger than UDP
but TCP comes in in the same order at it was send and no packages will be lost.
If they are sequential, and if they must be 100% reliable. A lot of game information is already outdated the next packet, and such packets don't have to be resent. Moreover, with TCP if packet N-1 is missing, packet N won't be passed to the client, thus waiting for resend.For UDP packages you have collect them all and bring it in the right order
and if an UDP package are missing you have to send an extra message to the server.
With an own simple integrity system and packet based communications instead of streams, this can be avoided with UDP.
Re: udp networking in freebasic.
viewtopic.php?t=25618, not sure where Boromir got it from.Rainwulf wrote:Where do you get network.bi from? Been looking for half an hour and still cant find it.
Re: udp networking in freebasic.
Who? My / Boromirs network.bi is posted above.Rainwulf wrote:Where do you get network.bi from? Been looking for half an hour and still cant find it.
My version is from 2010, small changes might be needed.
Re: udp networking in freebasic.
Yea im an bright and didn't read the post properly.
What are those "FD" commands? I ended up using an SDL example that worked perfectly, but it involves having to have the SDL dlls.
As well, never seen the timeout command either. A few more comments would help a lot!
The network.bi would work perfectly, i just want to fully understand the code before i implement it.
What are those "FD" commands? I ended up using an SDL example that worked perfectly, but it involves having to have the SDL dlls.
As well, never seen the timeout command either. A few more comments would help a lot!
The network.bi would work perfectly, i just want to fully understand the code before i implement it.
Re: udp networking in freebasic.
FD, see:
https://beej.us/guide/bgnet/html/multi/advanced.html
edit: The timeout command is related to this. Instead of a separate thread that waits 'forever' on data, we check and wait for data until timeout and continue main loop (with or without data received). No other threads needed.
It has been a while since I played with this, I could be wrong.
https://beej.us/guide/bgnet/html/multi/advanced.html
edit: The timeout command is related to this. Instead of a separate thread that waits 'forever' on data, we check and wait for data until timeout and continue main loop (with or without data received). No other threads needed.
It has been a while since I played with this, I could be wrong.