Atomic write on an unix socket?
NickName:Gui13 Ask DateTime:2011-01-12T22:10:49

Atomic write on an unix socket?

I'm trying to choose between pipes and unix sockets for an IPC mechanism.
Both support the select() and epoll() functions which is great.

Now, pipes have a 4kB (as of today) "atomic" write, which is guaranteed by the Linux Kernel.
Does such a feature exists in the case of unix sockets? I couldn't find any document stating this explicitely.

Say I use a UNIX socket and I write x bytes of data from my client. Am I sure that these x bytes will be written on the server end of the socket when my server's select() cracks?

On the same subject, would using SOCK_DGRAM ensure that writes are atomic (if such a guarantee is possible), since datagrams are supposed to be single well-defined messages?
What would then be the difference using SOCK_STREAM as a transfer mode?

Thanks in advance.

Copyright Notice:Content Author:「Gui13」,Reproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/4669710/atomic-write-on-an-unix-socket

Answers
JB. 2011-01-12T19:30:02

Pipes\n\nYes the non-blocking capacity is usually 4KB, but for maximum portability you'd probably be better off using the PIPE_BUF constant. An alternative is to use non-blocking I/O.\n\nMore information than you want to know in man 7 pipe.\n\nUnix datagram sockets\n\nWrites using the send family of functions on datagram sockets are indeed guaranteed to be atomic. In the case of Linux, they're reliable as well, and preserve ordering. (which makes the recent introduction of SOCK_SEQPACKET a bit confusing to me) Much information about this in man 7 unix.\n\nThe maximum datagram size is socket-dependent. It's accessed using getsockopt/setsockopt on SO_SNDBUF. On Linux systems, it ranges between 2048 and wmem_max, with a default of wmem_default. For example on my system, wmem_default = wmem_max = 112640. (you can read them from /proc/sys/net/core) Most relevant documentation about this is in man 7 socket around the SO_SNDBUF option. I recommend you read it yourself, as the capacity doubling behavior it describes can be a bit confusing at first.\n\nPractical differences between stream and datagram\n\nStream sockets only work connected. This mostly means they can only communicate with one peer at a time. As streams, they're not guaranteed to preserve \"message boundaries\".\n\nDatagram sockets are disconnected. They can (theoretically) communicate with multiple peers at a time. They preserve message boundaries.\n\n[I suppose the new SOCK_SEQPACKET is in between: connected and boundary-preserving.]\n\nOn Linux, both are reliable and preserve message ordering. If you use them to transmit stream data, they tend to perform similarly. So just use the one that matches your flow, and let the kernel handle buffering for you.\n\nCrude benchmark comparing stream, datagram, and pipes:\n\n# unix stream 0:05.67\nsocat UNIX-LISTEN:u OPEN:/dev/null &\nuntil [[ -S u ]]; do :;done\ntime socat OPEN:large-file UNIX-CONNECT:u\n\n# unix datagram 0:05.12\nsocat UNIX-RECV:u OPEN:/dev/null &\nuntil [[ -S u ]]; do :;done\ntime socat OPEN:large-file UNIX-SENDTO:u\n\n# pipe 0:05.44\nsocat PIPE:p,rdonly=1 OPEN:/dev/null &\nuntil [[ -p p ]]; do :;done\ntime socat OPEN:large-file PIPE:p\n\n\nNothing statistically significant here. My bottleneck is likely reading large-file.",


More about “Atomic write on an unix socket?” related questions

Atomic write on an unix socket?

I'm trying to choose between pipes and unix sockets for an IPC mechanism. Both support the select() and epoll() functions which is great. Now, pipes have a 4kB (as of today) "atomic" write, which is

Show Detail

How to read from and write to a Unix domain socket in Pharo?

my application needs to read and write to a Unix domain socket. How can I do that from Pharo?

Show Detail

Using netcat to pipe unix socket to tcp socket

I am trying to expose a unix socket as a tcp socket using this command: nc -lkv 44444 | nc -Uv /var/run/docker.sock When I try to access localhost:44444/containers/json from a browser, it doesn't...

Show Detail

How to create Unix Domain Socket with a specific permissions in C?

I have a simple code, like: sockaddr_un address; address.sun_family = AF_UNIX; strcpy(address.sun_path, path); unlink(path); int fd = socket(AF_UNIX, SOCK_STREAM, 0); bind(fd, (sockaddr*)(&ad...

Show Detail

How to use python or perl to write unix dgram socket client?

A unix dgram socket server has already been created. How to use python or perl to write a client? Below code is not working, returns "Connection refused". (python 2.7.6) #!/usr/bin/python import

Show Detail

AF_UNIX socket server write to itself in C

Can a socket server created with socket(AF_UNIX, SOCK_STREAM, 0) write to itself? I'm asking this becouse the first send is ignored if it was from the same server to the same server, but if it a cl...

Show Detail

Why is the select call not blocking on a unix domain socket?

I googled a lot and didn't get an answer, hence posting it here. In the following C program(the server code) I want a Unix domain socket server that's listening at /tmp/unix-test-socket. My probl...

Show Detail

UNIX socket connection refused

Under OS-X, I've got process named 'listener' that is waiting on 'accept' to read data from local unix socket named listener_socket. unfortunately, any attempt to connect that socket terminate in '

Show Detail

UNIX Socket permissions (Linux)

I am using UNIX sockets in C to develop a server. From the manual: In the Linux implementation, sockets which are visible in the filesystem honor the per‐ missions of the directory they...

Show Detail

Reusing PHP Unix Socket Files

I'm working on an IPC system for the backend of a web IM client coded in PHP. I'm trying to implement Unix sockets, but am having trouble reusing the created socket file. Here is code that listens ...

Show Detail