SendTo() RecvFrom()
BlitzMax Forums/BlitzMax Module Tweaks/SendTo() RecvFrom()
| ||
Not yet implemented as of v1.10, these 2 Methods extend the send & recieve capability of sockets. SendTo() works similar to .Send(), except with .Send() you're supposed to connect to a socket before using it. With .SendTo() you do not have to connect a socket first, you simply specify the destination IP & Port. RecvFrom() works just as .Recv() does, but you also pass the method two Integer variables (srcIP & srcPort). After the call to RecvFrom() (if there was data in the socket), the srcIP & srcPort variables will be filled with the IP & Port of the sender. Add this code in '\mod\brl.mod\socket.mod\socket.bmx' somewhere after 'Type TSocket', compile with command line 'bmk makemods brl.socket' Tested & working in Win32, they *should* work in Linux/Mac Cya! Tom Method SendTo( buf:Byte Ptr,count,destIP,destPort,flags=0 ) Local n=sendto_( _socket,buf,count,flags,destIP,destPort ) If n<0 Return 0 Return n End Method Method RecvFrom( buf:Byte Ptr,count,srcIP Var,srcPort Var,flags=0 ) Local n=recvfrom_( _socket,buf,count,flags,srcIP,srcPort ) If n<0 Return 0 Return n End Method |
| ||
Hi! Problem if you use recv or recvfrom with an udp socket is that you must read the complete size of the data buffer. If you don't do this, then the message is cut to specific size and the rest where trashed. Here the example for the UDPStream: you would for example send a simple message to a specific ip, you can do this with: Global Stream:TUDPStream Stream = New TUDPStream Stream.SetLocalPort(4321) Stream.SetRemotePort(1234) Stream.SetRemoteIP(TNetwork.IntIP("127.0.0.1")) Stream.WriteLine("Hello World") Stream.Close() End But if you would receive a message like: Global Stream:TUDPStream Stream = New TUDPStream Stream.SetLocalPort(1234) While Not KeyDown(KEY_ESCAPE) If Stream.ReadAvail() Then While Not Stream.Eof() Print ">"+Stream.ReadLine() Wend Stream.SetRemoteIP(Stream.GetMessageIP()) Stream.SetRemotePort(Stream.GetMessagePort()) Stream.WriteLine("OK") EndIf Wend Stream.Close() End It is not work, becouse ReadLine reads byte by byte and not the full databuffer. GetMessageIP/Port does work, but only one byte are analysted complete. Any idea how do solve this? cu olli |
| ||
Hi Vertex, i have a idea using banks to buffer the data and the sending the bank with a extra Method. See you Tim |
| ||
Gehilfe: Hmm, yes, that was what Blitz3D do with RecvUDPMsg. RecvUDPMsg reads all I think in a internal Blitz buffer and ReadLine and so on reads out of this buffer. But it must can do with recvfrom only. A TCP Socket can do this. I must test setsockop with a peek parameter, but I think, this does only work with windows. cu olli |
| ||
I'm sorry but I don't get the problem. As far as I know, RecvFrom works for me? And I don't buffer. With UDP you get a message or not? I think I've missed something but why would you ever, want to not read the whole UDP message? Please explain more, I can probably help you then. |
| ||
"Hello World" consist of 13(String+Chr(13)+Chr(10) ) Bytes. From brl.mod\stream.mod\stream.bmx: Method ReadLine$() Local str$,buf:Byte[1024],p Repeat Local n:Byte If Read( Varptr n,1 )<>1 Exit If n=0 Exit If n=10 Exit If n=13 Continue buf[p]=n ; p:+1 If p<>buf.length Continue str:+String.FromBytes(buf,p) p=0 Forever If p str:+String.FromBytes(buf,p) Return str End Method You see, ReadLine want to read on this example 13 Bytes individually. One Byte need 1 call of recvfrom. The networkbuffer consist of the 13 bytes. If you call recvfrom with 1 Byte size, than recvfrom returns SOCKET_ERROR and WSAGetlastError returns 10040 -> WSAEMSGSIZE. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/recvfrom_2.asp WSAEMSGSIZE: The message was too large to fit into the specified buffer and was truncated. A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram was smaller than the datagram itself. Datagram Socket = UDP Socket So 1 Byte is read, and the other 12 Bytes are deleted from the networkbuffer. A second call of recvfrom will fall. cu olli |
| ||
Vertex my Version with Buffering is running well. And some Sampels Const Port = 1234 Global Stream:TUDPStream Stream = New TUDPStream If Not Stream.SetLocalPort(Port) Then RuntimeError "Server can not bind to port: "+ Port Repeat Delay 200 If Stream.Recv() While Not Stream.eof() Print "New Byte:" + Stream.ReadByte() Wend EndIf FlushMem() Forever Const Port = 5200 Global Stream:TUDPStream Stream = New TUDPStream If Not Stream.SetLocalPort(Port) Then RuntimeError "Server can not bind to port: "+ Port Stream.SetRemoteIP TNetwork.IntIP("127.0.0.1") Stream.SetRemotePort 1234 Stream.WriteByte(33) Stream.WriteByte(33) Stream.WriteByte(33) Stream.WriteByte(33) Stream.WriteByte(33) Stream.WriteByte(33) Stream.WriteByte(33) Stream.Send() |
| ||
I still don't get what you're on about. I'm not using streams, and as Wave said, sendTo() & recvFrom() are working fine for me too. If there's a problem with sockets when using the additional code I posted, can you show us a simple example? Thanks Tom |