#how do I know what buffer size to use when receiving data over tcp socket
65 messages · Page 1 of 1 (latest)
io.Copy + bytes.Buffer
no need to manually pass a slice buffer to the Read method.
The way you are meant to use io.Reader is in a streaming way, so you make your buffer let's say 32KiB and reuse it over and over
if you really just want everything, as @umbral pollen suggested.
You can also call io.ReadAll
but theses solutions can allocate lots of memory and are slow because you can't do work before you got everything
@mighty willow what are you doing with the images ?
io.readall but its the net library ?
io.ReadAll takes in an io.Reader
which is an interface implement by the tcp connection
so you can pass a tcp connection to io.ReadAll
ahh I see! I will try that, that sounds a lot simples
I am going to send the images to a webrtc connection in the future, right now I am just trying to send them for testing purposes
it's not a great solution, uses lots of memory and is most often slower than streaming the file instead
how are you using it ? Writing it to a file ? Decoding it using the image librairy ?
you want to stream video between .net and golang ?
yes, it won't be production, I will probably use a better cross process communication in the future. But yes
video streaming from .net to golang and then next step attach it to a webrtc stream
you might need to be carefull with performance. A 1080p video stream is around 1Gbps
that a problem you can solve later however
yeah that is tomorrows problem 🙂
Last question, do you open a TCP connection per image or do you reuse the same one ?
same connection
Ok so, you can't use io.ReadAll.
You could but it only returns after having red everything
So you will run out of memory very quickly as it keeps reading
and you can't stream images over webrtc
no it needs to be encoded also
like ?
not gotten to that yet, I will be using pion and maybe ffmpeg in some capacity
Ah so you aren't literally streaming images
so instead of io.ReadAll I should use?
you will be using a video encoder ?
Depends, what is the API pion requires ?
.net video frame -> golang using websocket -> video encoding -> webrtc stream
is the websocket going through multiple machines ?
not sure yet to be honest, just wanted to start by sending the images from .net to golang and golang seemed like a good first step
same machine
i might use named pipes in the future
Yeah that sounds like a better idea.
Honnestly I would even use two of them and do that using named pipes:
.net → ffmpeg → golang → webrtc
was using .net webrtc framework but the support of webrtc was not stable and the ffmpeg adapter was even worse. No hardware encoding possible and very little control overall
You can invoke ffmpeg cli
and then access pipes
kinda writting your own wrapper in that way
never done that, maybe a good option
Anyway to send images, your best bet is to have .net preffix them with the length, read them one by one and reuse buffers
func DecodeFrames(r io.Reader, useFrame([]byte) error) error {
buffer := make([]byte, 4)
for {
_, err := io.ReadFull(r, buffer[:4])
if err != nil { return err }
size := binary.LittleEndian.Uint32(buffer)
if uint(len(buffer)) < uint(size) {
buffer = make([]byte, size)
}
_, err = io.ReadFull(r, buffer[:size])
if err != nil {
if err == io.EOF { err = io.ErrUnexpectedEOF }
return err
}
err = useFrame(buffer[:size])
if err != nil { return err }
}
}
Then in .net you need to send the size of the frame first, as 4 byte little endian (you can use bigendian if you want, both just needs to agree) and then the image
the point is that then you can easily know where one frame begins and when one ends
You also maybe want to add a limit on size and error if it is too big, because right now each connection can allocate 4GiB images which could use a lot of memory and crash the app
thank you that makes total sense!
just curious about the code
if uint(len(buffer)) < uint(size) {
wont that like always be true, reusing the 4 byte[] that is used to get buffer size which is usually smaller than the data buffer itself?
the buffer is outside the loop
you are correct this will most likely always be true in the first iteration
but after that the next image can reuse the buffer of the previous image
btw I realised I made a mistake the second .ReadFull call needs to be limited to size
_, err = io.ReadFull(r, buffer[:size])