NetLib like BlitzClassic

BlitzMax Forums/BlitzMax Module Tweaks/NetLib like BlitzClassic

Vertex(Posted 2005) [#1]
Hi!
I'am working currently on a networklibrary like BlitzClassic.

To import the socket api, pls use this code(socket.bmx):
http://blitzbasic.com/codearcs/codearcs.php?code=1270

this is a beta version that doesn't work but it is a start:
see last post


- Don't know how work CountHostIPs and HostIP.
- Don't know how work ReadAvail
- Don't hnow how work CopyStream
- Don't know how realy how work the TStream-Modul
- Don't know how I can connect with a localport and a serverport.
I made it so: s_connect with the local port, and use in s_recvfrom / s_sendto with the serverport, but i can't test it, becouse I havn#t a proxy server.

cu olli


Vertex(Posted 2005) [#2]
OK, I have delete this code and wirtten new...

see last post


Now needs to be use InitNetwork and CloseNetwork.
cu olli


Vertex(Posted 2005) [#3]
New Version:
see last post


cu olli


Kanati(Posted 2005) [#4]
good start... looking forward to it.


Vertex(Posted 2005) [#5]
Yes :)

Here the new version with udp support(I don't test RecvUDPMsg :))

Local tClient:TTCPClient 

If InitNetwork() = False Then 
   Print "Error: Can't initialize network" 
   Delay 2000 ; End 
EndIf 

tClient = OpenTCPStream("192.168.2.1", 80) 
If tClient = Null Then 
   CloseNetwork() 
   Print "Error: Can't connect to server" 
   Delay 2000 ; End 
EndIf 

WriteLine tClient, "GET http://192.168.2.1/ HTTP/1.0" 
WriteLine tClient, "" 
WriteLine tClient, "" 

While Not Eof(tClient) 
   Print ReadLine(tClient) 
Wend 

CloseTCPStream tClient 

CloseNetwork() 
Delay 2000 ; End


192.168.2.1 is my router

Edit: OK, now SendUDPMsg works right!


Vertex(Posted 2005) [#6]
Sooo, UDP works good, fixed EOF Bug in UDP. TCP will be update soon...

see last post


A cool code vom SucoX(german messageboard):
Strict 
Import "netlib.bmx"

Const IC_JOIN:int           = 1
Const IC_JOIN_ACCEPT:int    = 2
Const IC_POSITION:int       = 3

Const ScreenWidth:int  = 800
Const ScreenHeight:int = 600
Const ScreenDepth:int  = 0



Global ConnectionStream:int = 0
Global ConnectionPort:int   = 0
Global ConnectionIP:int     = 0
Global GameNick:string      = ""
Global UdpZeug()





TUser.ObjectList = New TList


Type TUser

    Global ObjectList:TList 
    
    
    Field IP:int
    Field Port:int
    Field Name:string 


    Function Create:TUser()
        Local TempObject:TUser = New TUser
        
        Self.ObjectList.AddLast(TempObject)
        Return TempObject
    End Function 
    
    
    Function SendToAll()

        For Local TempObject:TUser = EachIn Self.ObjectList
            sendUdpmsg(ConnectionStream,TempObject.IP,TempObject.Port)
        Next 
    End Function 
    
    
End Type 
















Function GetKind()

    Local TempCommand:string = ""
    Local LoopEnd            = 0
    
    TempCommand = Input("Host[1], Join[2]. Please choose one ")
    If Int(TempCommand) = 1
        AnmeldungHost()
    Else If Int(TempCommand) = 2
        AnmeldungClient()
    Else 
        Notify("False choosen!")
        End  
    EndIf

End Function 




Function AnmeldungClient()

Local ip:string    = ""
Local Port:string  = ""
Local Nick:string  = ""
Local TempEnd:int  = 0

Repeat 

    ip    = Input("Server IP: ")
    port  = Input("Server Port: ")
    Nick  = Input("nick: ")
    
    ConnectionIP   = IntIP(ip)
    ConnectionPort = Int(Port)
    
    If ConnectionIP = 0
        Print "Please enter a right ip!"
        Continue 
    EndIf
    
    If ConnectionPort = 0
        Print "Please enter a right port!"
        Continue 
    EndIf
    
    If Nick.length=0 
        Print "Please enter a right nick!"
        Continue 
    EndIf
    
    TempEnd = 1
    GameNick = Nick

Until TempEnd = 1



UdpZeug = ClientSeitig

Print "Apllication starting. Please wait!"
Print "....."

ConnectionStream = CreateUdpStream()

If ConnectionStream = 0
    Notify("Networkstream can't created")
    End 
EndIf

SendeAnmeldung()

End Function 




Function SendeAnmeldung()
    
    Local TempEnd     = 0
    Local TempCommand = 0
    

    Writeint(ConnectionStream,IC_JOIN)
    WriteLine(ConnectionStream,GameNick)
    SendUdpMsg(ConnectionStream,ConnectionIp,ConnectionPort)
    
    Repeat 
    
        If RecvUdpMsg(ConnectionStream)
            
            TempCommand = Readint(ConnectionStream)
            
            If TempCommand<>IC_JOIN_ACCEPT
                Continue 
            EndIf 
            
            TempEnd = 1
            
        EndIf 
    
    Until TempEnd = 1 
    
    Print "Connection OK!"
    Print "Starting game!"
    
End Function 





Function AnmeldungHost()

Local Port:string = Input("Port: ")
ConnectionPort = Int(Port)

If ConnectionPort = 0
    Notify("Please enter a Right port!")
    End 
EndIf

UdpZeug = ServerSeitig

Print "Server will be created. Please wait!"
Print "...."

ConnectionStream = CreateUdpStream(ConnectionPort)

If ConnectionStream = 0
    Notify("Networkstream can't created")
    End 
EndIf

Print "Server has started"

End Function 








Function AcceptUser()

    Local TempNick:string = ReadLine(ConnectionStream)
            
    If TempNick.length = 0
        Print "User without nick has been entered"
        Return False 
    EndIf
            
    Local TempUser:TUser = TUser.Create()
    TempUser.name        = TempNick
    TempUser.ip          = UdpMsgIp(ConnectionStream)
    TempUser.Port        = UdpMsgPort(ConnectionStream)
            
    Print "User "+TempUser.Name+" has connect"
    Print "IP : "+TempUser.IP
    Print "Port : "+TempUser.Port
            
    WriteInt(ConnectionStream,IC_JOIN_ACCEPT)
    sendUdpMsg(ConnectionStream,TempUser.ip,TempUser.Port)
    
End Function 









Function ServerSeitig()

    Local TempCommand = 0
    
    
    If RecvUdpMsg(ConnectionStream)
    
        TempCommand = Readint(ConnectionStream)
        
        Select TempCommand
        
            Case IC_JOIN
                Print "NEW USER"    
                AcceptUser()
            
            Case IC_POSITION
            
                Print "RECEIVED A MESSAGE"    
                Local x:int = readint(ConnectionStream)
                Local y:int = Readint(ConnectionStream)
                
                
                OvalX = x
                OvalY = y

        End Select 
    
    EndIf 
    
    
    
    If MilliSecs()-SendTime=>500
        If CountList(TUser.ObjectList)>0
            WriteInt(ConnectionStream,IC_POSITION)
            WriteInt(ConnectionStream,PlayerX)
            WriteInt(ConnectionStream,PlayerY)
            TUser.SendToAll()
        EndIf
        
        SendTime = MilliSecs()
    EndIf
    

End Function






Function ClientSeitig()
    
    Local TempCommand = 0
    
    
    If RecvUdpMsg(ConnectionStream)
        
        TempCommand = Readint(ConnectionStream)
        
        Select TempCommand
        
            Case IC_POSITION
                Print "RECEIVED A MESSAGE"    
                Local x:int = Readint(ConnectionStream)
                Local y:int = Readint(ConnectionStream)
                OvalX = x
                OvalY = y
                
                
        End Select 

    EndIf 
    
    If MilliSecs()-SendTime=>500
        WriteInt(ConnectionStream,IC_POSITION)
        WriteInt(ConnectionStream,PlayerX)
        WriteInt(ConnectionStream,PlayerY)
        SendUdpMsg(ConnectionStream,ConnectionIp,ConnectionPort)
        SendTime = MilliSecs()
    EndIf
    
    
End Function 




Print "Starting network..."

InitNetwork()


GetKind()

Print "Ready"










Graphics ScreenWidth,ScreenHeight,ScreenDepth




Global OvalX:int = 100
Global OvalY:int = 100



Global PlayerX:int = 200
Global PlayerY:int = 200

Global SendTime:int = MilliSecs()


Repeat
Cls

Delay(10)




UdpZeug()


DrawOval OvalX,OvalY,20,20
DrawOval PlayerX,PlayerY,50,50

PlayerX = MouseX()
PlayerY = MouseY()


Flip
FlushMem()
Until KeyHit(KEY_ESCAPE)



Function IntIP:int(Ip:string)
    Return s_htonl(s_inet_addr(Ip))
End Function


Fast "translation" by me(sorry Suco :)))

Test it with him correctly!
cu olli


Vertex(Posted 2005) [#7]
Addet CountHostIPs and HostIP(i hatttttteeeee pointer!!!!!)
see last post


cu olli


Vertex(Posted 2005) [#8]
You can download now the mod
http://vertex.art-fx.org/bnet.zip
\mod\pub.mod\bnet.mod\

fixed little bugs with tcp - eof.
cu olli

Edit: Now ReadAvail avariable!


Vertex(Posted 2005) [#9]
http://vertex.art-fx.org/bnet.zip

Now for Linux avariable. I hate Linux! [Fry] Linux!
-> Don't test it with Linux! -> You must test it with Linux!

cu olli


Jeroen(Posted 2005) [#10]
Hi Vertex,

Is your intention to create the same functionality as Blitzplay has? (e.g syncronised game clock, UDP with basic packet checking, etc)


Vertex(Posted 2005) [#11]
Hi!
Firstly, I will fix all bugs and porting to linux.

Version 1.36 fixed some bugs for AcceptTCPStream Clients, fixed OpenTCPStream bug under WinXP(addet for this a hostent-structure), InitNetwork and CloseNetwork are automaticaly started/endet ands works perfectly I think :)

But I have found out a little bug:
www = OpenTCPStream("vertex.art-fx.org", 80) 
If Not www Then 
   Notify "Konnte nicht verbinden!" 
   End 
EndIf 

WriteLine www, "GET  HTTP/1.0" 
WriteLine www, "" 

For I = 1 To 10 
   Print ReadLine(www) 
Next 

stream = CreateFile("temp.png") 
While Not Eof(www) 
   WriteByte stream, ReadByte(www) 
Wend 

CloseFile stream 
CloseTCPStream www 

Graphics 323, 253, 0, 0 
image = LoadImage("temp.png") 
DrawImage image, 0, 0 
Flip 
WaitKey 
End


If there many bytes to download, ReadByte will return a error(becouse no things to receive for the client(checket with s_FD_ISSET)). I don't know, how Mark Sibly has solve this problem in BlitzClassic.

The linuxversion don't work! s_gethostbyaddr canceld without error the complete program. And s_select needs athor parameters in linux as windows(so no checking for incomming data). But CountHostIPs runs :)

cu olli


Jeroen(Posted 2005) [#12]
hehe it seems the forum has a bug where stuff inside the [ code ] tag can still be parsed and displayed as an image.


Vertex(Posted 2005) [#13]
Jup, it's funny :)

Now I have found out, that s_select say me, I can read data. Wenn I read the data with s_recv, then s_recv return me a error (-1 = SOCKET_ERROR -> "Connection was aborted"). When I try to close this socket, and reconnect, then say me s_select that data readvariable but s_recv is blocking all the time.

Dear Mark Sibly, how you make this in BlitzClassic? :)

cu olli


Vertex(Posted 2005) [#14]
Now avariable Version 1.37 for Windows.
http://vertex.art-fx.org/bnet.zip

Bug is fixed, and I have addet a english help textfile.

cu olli


Richard B(Posted 2005) [#15]
Waiting eagerly for the OSX version :-)

many thanks,
Richard.


Jeroen(Posted 2005) [#16]
Vertex, if you need someone to test the OSX version, please contact me.


Richard B(Posted 2005) [#17]
Vertex, I am having a go at porting your socket code to OSX. Just one question about your Extern calls:

Extern "OS"
Function s_accept:Int(iSocket:Int, tAddr:Byte Ptr, ipAddrLen:Int Ptr) = "accept@12"

etc. As I understand it Extern's link to c code etc, but what does your code links to? Also, what does the "accept@12" part correspnd to - is it a Windows call?

thanks,
Richard.

PS Jeroen if you want to team on on this...see web site for email address


Vertex(Posted 2005) [#18]
Hi!
I think that Linux and OSX have the full Berkeley-Socket-Support. The problems are not sooo big:
- gethostbyname does not work with my hostent strucutre(needed for example in CreateTCPServer or IntIP)
- select needs the highes socket discriptor + 1. But I don't know, how I can handle it.(needed in all recieving functions like RecvUDPMsg)

The rest I think, works.

Richard B:
Thats not a link to a c code, it's a link to a operatingsystem-api. On Windows is that a link to WinAPI(more exactly: wsock32.dll).

There are little differences between Winsock and Linux(or OSX). I must use under linux for example
Function s_accept:Int(iSocket:Int, tAddr:Byte Ptr, ipAddrLen:Int Ptr) = "accept" and not "accept@". Or the "closesocket" function is known as "close".

To team this project is a good idea, but I must make sure that OSX have nearly the same socket-structure.

cu olli


Vertex(Posted 2005) [#19]
Now avariable 1.41 http://vertex.art-fx.org/bnet.zip

Fixed some bugs last time.

The last bug was:
If you have a server with CreateTCPServer and client with AcceptTCPClient has disconnected, then Eof does not return -1. Now Eof return -1

In BlitzClassic you have no possibilities to check, if a client has disconnect, in BNet you have :)

Eof = 0 -> Data can read
Eof = 1 -> No data to read
Eof = -1 -> Client has disconnected

For example:
Strict

Type THTTPClient
   Global List : TList
   
   Field Stream : TTCPClient
End Type

Global Server     : TTCPServer
Global Client     : TTCPClient
Global HTTPClient : THTTPClient

THTTPClient.List = CreateList()

Server = CreateTCPServer(80)
If Server = Null Then RuntimeError "Konnte Server nicht erstellen!"

TCPTimeouts(0, 1000)

Repeat
   Client = AcceptTCPStream(Server)
   If Client <> Null Then
      HTTPClient = New THTTPClient
      HTTPClient.Stream = Client
      THTTPClient.List.AddLast(HTTPClient)
      Print "New client!: "+DottedIP(TCPStreamIP(Client))
   EndIf
   
   For HTTPClient = EachIn THTTPClient.List
      If Eof(HTTPClient.Stream) = -1 Then
         Print "Client disconnected!: "+DottedIP(TCPStreamIP(HTTPClient.Stream))
         THTTPClient.List.Remove(HTTPClient)
         Continue
      EndIf
     
     
      While Not HTTPClient.Stream.Eof()
         Print DottedIP(TCPStreamIP(HTTPClient.Stream))+" "+..
               ReadLine(HTTPClient.Stream)
      Wend
   Next
Forever


Just type localhost in your browser, and then stop it. Blitz will display "Client disconnected!: 127.0.0.1"

cu olli


Vertex(Posted 2005) [#20]
http://vertex.art-fx.org/bnet.zip <- New Betaversion for Linux und MacOS!

Thx to BigMichi, he let me programm with a remotecontrol on Linux.

MacOS-Version is the Linux-Version with modified FIONREAD-Const.

Now you must type Framework Pub.BNet! It is becouse the new socked.mod bye Mark. (Just see the examples)

Please test the examples!

cu olli


ckob(Posted 2006) [#21]
you still working on this vertex?


Vertex(Posted 2006) [#22]
http://vertex.art-fx.org/ (BNet) <- here you can find the newest.
cu olli


ckob(Posted 2006) [#23]
yeah i get some errors when running it on this line


InitNetwork()


Vertex(Posted 2006) [#24]
Oh, fucking shit, the examples are very old. You needn't InitNetwork(). If I have time ... (hmmm, I use yours will future to much :P )
cu olli