I would like to increase the recieve buffer size of a UDP socket, but I don’t see how to do it. In C++ I would do
setsockopt(sd, SOL_SOCKET, SO_RCVBUF, &sockbufsize, (socklen_t)sizeof(sockbufsize));
But the closest function I can find is setopt
which doesn’t seem to support this. Any ideas?
It looks like maybe I want to call int uv_recv_buffer_size(uv_handle_t* handle, int* value)
. The libuv docs say "Gets or sets the size of the receive buffer that the operating system uses for the socket. If *value == 0, it will return the current receive buffer size, otherwise it will use *value to set the new receive buffer size. This function works for TCP, pipe and UDP handles on Unix and for TCP and UDP handles on Windows.
So I tried
udpsock = UDPSocket()
err = ccall(:uv_recv_buffer_size, Cint, (Ptr{Void}, Ptr{Cint}), udpsock.handle, Cint[0])
But I’m getting err=-9
which suggests I’m probably doing something wrong.
We also have problems with receiving UDP messages in Julia: Many of them get lost. I am not sure, if the buffersize is the problem, could also be something else.
Example code:
using DataStructures
# disable SIG_INT
println("To termiate the logger, press <CTRL>+<C>!")
ccall(:jl_exit_on_sigint, Void, (Cint,), 0)
# use an array with one element for global variables, such that they can be declared as const
const terminate = [false]
# create a queue for buffering incoming messages
const q = Queue(String)
# background loop for receiving UDP messages, terminated with <ctrl> + <c>
function receiveData(server_ip)
global terminate
udpsock = UDPSocket()
# setopt(udpsock, enable_broadcast=true)
bind(udpsock, server_ip, port)
i = 0
try
while true
msg = String(copy(recv(udpsock)))
enqueue!(q, msg)
end
catch my_exception
if isa(my_exception, InterruptException)
close(udpsock)
terminate[1] = true
end
end
end
server_ip = IPv4("0.0.0.0")
@async receiveData(server_ip) # start the background task of receiving UDP packages
I managed to get uv_recv_buffer_size
to work with the following:
port = 40788
udpsock = UDPSocket()
didbind = bind(udpsock,ip"127.0.0.1",port)
@assert didbind
arg = Ref{Cint}(0) # pass 0 to read the value
Base.uv_error("buffer size",ccall(:uv_recv_buffer_size, Cint, (Ptr{Void}, Ptr{Cint}), udpsock.handle, arg))
@show arg
arg = Ref{Cint}(100000) # pass nonzero to set the value (doubled on linux)
Base.uv_error("buffer size",ccall(:uv_recv_buffer_size, Cint, (Ptr{Void}, Ptr{Cint}), udpsock.handle, arg))
@show arg
arg = Ref{Cint}(0) # pass 0 to read the value
Base.uv_error("buffer size",ccall(:uv_recv_buffer_size, Cint, (Ptr{Void}, Ptr{Cint}), udpsock.handle, arg))
@show arg
2 Likes