Set UDPSocket reciever buffer size?

networking

#1

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?


#2

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.


#3

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.


#4

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

#5

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