1

I am writing an application that sends parallel ICMP packets, and receives them. To help with the parallelism and synchronization, I have designed multiple writers (and sockets), and a single reader.

Let's say I have 256 writers and one reader. This means I created 257 raw sockets. From what I learned, because raw sockets work lower than the transport level, kernel copies every response from the recipients to all raw sockets. Even though I am able to filter or discard them, I don't want the 256 writer sockets to receive all this data from the kernel and spend unnecessary resources (imagine more writers). I don't know if lot's of raw sockets are a burden for the kernel, couldn't find any information about that, so I could also use help in that direction.

I wanted to prevent the writer raw sockets from receiving any data, even though filling their buffer up and let the kernel drop packets is an option.

What didn't help me:

close vs shutdown socket? (my research shows shutdown doesn't work with connectionless sockets)

create SOCK_RAW socket just for sending data without any recvform() (decreasing the receive buffer size to 0 doesn't seem to create the desired effect, also it is mentioned in the unix documentations the minimum is 256 bytes. The goal is to prevent kernel from ever consider the writer sockets for received data)

Rockybilly
  • 2,938
  • 1
  • 13
  • 38
  • You should be able to use a single socket from multiple threads *and* processes. IIRC a write to a socket is atomic if the packet size is small enough so synchronization might not be needed. Packets are queued in the order they are written to the socket. However, reading is a different matter: If one thread or process reads from such a shared socket, it will simply receive what's in the buffer at the moment, without any knowledge if it's the correct thread/process to receive that data. And once data has been fetched, it's gone from the socket and its buffers. – Some programmer dude Aug 03 '22 at 15:28
  • 1
    I've built similar solutions in the past, and found that a good approach was to have a single thread, with a single socket serviced by epoll, which sent and received packets as appropriate. In practice, the throughput is excellent, and all of the complexity of synchronising data across threads is avoided. – Buffoonism Aug 03 '22 at 15:37

0 Answers0