Understanding Sockets

BlitzMax Forums/BlitzMax Programming/Understanding Sockets

Im really understanding hows this works, I have used the old Blitz3D TCPStream, but this is different, can someone tell me if there is something wrong in this code, because the Client side connects even know there isn't a host avalible..


Strict

Global TCP_SERVER
Global TCP_STREAM

Global ANSWER

Global Player

Function HostGame(port:Int)
	
	Local socket
	Local stream
	
	Print "Connecting..."
	
	socket = CreateTCPSocket()
	stream = CreateSocketStream(socket)
	BindSocket socket,port
	SocketListen socket,10
	
	Print "Connected"
	
	TCP_SERVER = socket
	Return stream
	
End Function

Function JoinGame(host:String,port:Int)

	Local socket
	Local stream
	
	Print "Connecting..."	
	
	socket = CreateTCPSocket()
	stream = CreateSocketStream(socket)
	BindSocket socket,port
	ConnectSocket socket,HostIp(host),port
	
	If SocketConnected(socket)=True
		Print "Connected"
	Else
		Print "Error connection failed to host!!"
	EndIf
	
	TCP_SERVER = socket
	Return stream	
	
End Function



i don't think you want to bind the client side socket ?

at least with "traditional" socket programming, you wouldn't want to do this on the client side.

Tony

I does it even if you don't bind the clien, I know it should fail I just don't know why its not.

This is quite good, gives you an understanding of sockets.
Information on TCP and networking
It's not BMax specific though.

And I thought you had to bind a socket unless you use _sendto() or get the socket from SocketAccept()?

Also if you want to use TCP like in Blitz3D there is a conversion which mimics the Blitz3D model with streams. See BNet
It should allow for very easy conversions of Blitz3D network programs.

yes wave your right about having to bind it..

I don't want to use any modules or libs, because I want to understand them myself.. so Im trying to use the raw socket..

I just need to figure out how to make a error check for if the host isn't around.

Ok, can't you then just wait until you receive something from the host socket on your client?

If Socket

	Local length = SocketReadAvail(Socket)
	If length > 0 'Got MSG?
	
		Local buf:Byte[length]
		Socket.Recv( buf,length)
		Data$ = String.FromBytes( buf,length )
		Print "Got "+length+" bytes"
		
	EndIf
	
EndIf


hmm okay I will try that out and see how it works,

are the types with Socket.Recv a undoc code or something??

Socket is of the TSocket Type which is a BlitzMax Type. Recv is a method. I might be using it wrong/unefficient. I'm more used to UDP.

You're missing SocketAccept()

You need to check a 'listening' socket to see if someone's trying to connect

Check for new connections every so often..
Local newSock:TSocket = SocketAccept(myListenSocket)
If newSock
  'Houston, we have a connection!
  'store the new socket in a player/client type e.t.c
End If
Something like that :)

mySocket.Recv() and .Send() are undocumented.
If newSock
  Local size:Int = SocketReadAvail(newSock)
  If size>0
    Local buffer:Byte[] = New Byte[size]
    newSock.Recv(buffer,size) 'transfer data in TCP socket to 'buffer'
    Print String.frombytes(buffer,buffer.length)
  End If
End If

Send() work in a similar way, create a buffer:byte[], fill it with your data, then newSock.Send(buffer,buffer.length)

Also, I've not tried using socket streams yet so I don't know if it's a better way to pipe data to/from a socket.

Tom

Well is UDP easyer to get workin with..

Im trying to get this figure out so I can starting workin on a multiplayer game of mine.

I would use your TNet, but I don't like how its type based.


Function JoinGame(host:String,port:Int)

	Local socket
	Local stream
	
	socket = CreateTCPSocket()
	stream = CreateSocketStream(socket)
	BindSocket socket,port
	ConnectSocket socket,HostIp(host),port
	
	Print "Connecting..."
	
	TCP_STREAM = stream
	Return socket	
	
End Function

answer = Proceed("Would you like to host this game?")

Select answer

	Case 0
		TCP_SERVER = JoinGame("127.0.0.1",6000)
		If TCP_SERVER
	
			Local avail = SocketReadAvail(TCP_SERVER)
	
			Repeat
		
			
		
			Until avail > 0
		
			Print "Connected"
		
		EndIf
	Case 1
		TCP_SERVER = HostGame(6000)
	Case -1
		End

End Select



This is what im doing.. but im sure its wrong.

You're using Int vars where you should be using TSocket, I dunno if max can do this but I think it would be better if you used the correct var types
Function JoinGame:TSocket(host:String,port:Int)
  Local socket:Tsocket = CreateTCPSocket()
  If Not socket
    Print "Couldn't Create a socket"
    Return Null
  End If
  
  If Not BindSocket(socket,port)
    Print "Couldn't bind socket to port "+port
    Return Null
  End If

  If Not ConnectSocket(socket,HostIP(host),port)
    Print "Couldn't connect to "+host+":"+port
    Return Null
  End If

  Print "Connected to "+host+":"+port
  Return socket	
End Function


But it's not type based? Or what do you mean? Atleast you don't need to use types in TNet. Except when you receive a msg.

Graphics 300,300,0

HostUDP( 8080 )

LastMSG$ = "No Message Received Yet"
While Not KeyHit(KEY_ESCAPE)
Cls
	UpdateTNet()

	DrawText "I'm the Host!",0,0
	DrawText "CHAT: [ "+LastMSG+" ] ",0,18
	DrawListOfAllClients(10,55)
	
	If KeyHit(Key_T) SendTCP( 1, "TCP" )'TCP Msg To ALL
	If KeyHit(Key_U) SendUDP( 1, "UDP" )'UDP Msg To ALL	
	
	If GetQuickMsg( 1 ) LastMSG = TNet.Data '<---
	
Flip
Wend


And I can easily add one line of code so instead of TNet.Data$ you can go TNetData$. If that's what you mean?

Thrust me if multiplayer is what you want you'll save a lot of time using a library (GNet, TNet or BNet). But if you want to learn sockets then you'll better get a book on the subject =)

@FBEpyon
I would use your TNet, but I don't like how its type based.

Please explain in more detail, perhaps it is something I can change? Your probably not alone in this matter. I want to make TNet as good as possible, for any coding style.

Have you ever used BlitzPlay??

Im looking for something thats simular to that easy to use..

I want single command system OpenTCP(1660) like thing..

TNet is easier to use than BlitzPlay. It should be as far as I know. The two are very similar.

I know BlitzPlay, that was what I used when I first started with BlitzBasic =) The basic idea of TNet comes from BlitzPlay. Like MessageTypes and Clients IDs to sort messages.

Checkout the simple chat-example at the TNet website to get a good understanding of how easy it is =)

hmmm

well I will look into it a bit more.. than later.. :P

is this going to be free??

It's free for non-commercial projects.