socketpair() limitations

It appears that socket create by socketpair(AF_LOCAL, SOCK_DGRAM) can’t take
a write() with more than 2k of data. Why? This works on Unices…
The send() and recv() calls do not work with it at all. I don’t know if they
should, but why not?

– igor

Igor Kovalenko <kovalenko@attbi.com> wrote:

It appears that socket create by socketpair(AF_LOCAL, SOCK_DGRAM) can’t take
a write() with more than 2k of data. Why? This works on Unices…

This is what the NetBSD default is. It analagous to net.inet.udp.sendspace
(see sysctl -a) but there is no sysctl to change it.

The send() and recv() calls do not work with it at all. I don’t know if they
should, but why not?

They seem to work for me:


#include <sys/socket.h>
#include <stdio.h>

int
main(void)
{
int fds[2];
char c;

socketpair(AF_LOCAL, SOCK_DGRAM, 0, fds);

if (send(fds[0], “a”, 1, 0) == -1) {
perror(“send”);
return 1;
}

if (recv(fds[1], &c, 1, 0) == -1) {
perror(“recv”);
return 1;
}

printf("%c\n", c);

return 0;
}

“Sean Boudreau” <seanb@node25.ott.qnx.com> wrote in message
news:bi00li$ejn$1@nntp.qnx.com

Igor Kovalenko <> kovalenko@attbi.com> > wrote:
It appears that socket create by socketpair(AF_LOCAL, SOCK_DGRAM) can’t
take
a write() with more than 2k of data. Why? This works on Unices…

This is what the NetBSD default is. It analagous to
net.inet.udp.sendspace
(see sysctl -a) but there is no sysctl to change it.

Oh. Maybe you should add sysctl then. Or increase the default. It works on
Linux & Solaris.

The send() and recv() calls do not work with it at all. I don’t know if
they
should, but why not?

They seem to work for me:

Ok, I’ll check again. Maybe there was some other problem with the code…

#include <sys/socket.h
#include <stdio.h

int
main(void)
{
int fds[2];
char c;

socketpair(AF_LOCAL, SOCK_DGRAM, 0, fds);

if (send(fds[0], “a”, 1, 0) == -1) {
perror(“send”);
return 1;
}

if (recv(fds[1], &c, 1, 0) == -1) {
perror(“recv”);
return 1;
}

printf("%c\n", c);

return 0;
}

Igor Kovalenko <kovalenko@attbi.com> wrote:

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:bi00li$ejn$> 1@nntp.qnx.com> …
Igor Kovalenko <> kovalenko@attbi.com> > wrote:
It appears that socket create by socketpair(AF_LOCAL, SOCK_DGRAM) can’t
take
a write() with more than 2k of data. Why? This works on Unices…

This is what the NetBSD default is. It analagous to
net.inet.udp.sendspace
(see sysctl -a) but there is no sysctl to change it.


Oh. Maybe you should add sysctl then. Or increase the default. It works on
Linux & Solaris.

You can change it on a per socket basis with SO_SNDBUF:



#include <sys/socket.h>
#include <stdio.h>

char buf[2049];

int
main(void)
{
int fds[2];
char c;
int size = sizeof(buf);

socketpair(AF_LOCAL, SOCK_DGRAM, 0, fds);

if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) == -1) {
perror(“setsockopt”);
return 1;
}

buf[0] = ‘a’;

if (send(fds[0], buf, sizeof(buf), 0) == -1) {
perror(“send”);
return 1;
}

if (recv(fds[1], &c, 1, 0) == -1) {
perror(“recv”);
return 1;
}

printf("%c\n", c);

return 0;
}

Thanks Sean, it works of course.

I actually thought of using that too, but then I turned to docs (for
setsockopt) and it said: ‘the system imposes an absolute limit on those
values and defaults to at least 16K’. So if it defaults to 16K, how come
it did not like anything above 2k?

Docs error?

Sean Boudreau wrote:

Igor Kovalenko <> kovalenko@attbi.com> > wrote:

“Sean Boudreau” <> seanb@node25.ott.qnx.com> > wrote in message
news:bi00li$ejn$> 1@nntp.qnx.com> …

Igor Kovalenko <> kovalenko@attbi.com> > wrote:

It appears that socket create by socketpair(AF_LOCAL, SOCK_DGRAM) can’t

take

a write() with more than 2k of data. Why? This works on Unices…

This is what the NetBSD default is. It analagous to

net.inet.udp.sendspace

(see sysctl -a) but there is no sysctl to change it.



Oh. Maybe you should add sysctl then. Or increase the default. It works on
Linux & Solaris.


You can change it on a per socket basis with SO_SNDBUF:



#include <sys/socket.h
#include <stdio.h

char buf[2049];

int
main(void)
{
int fds[2];
char c;
int size = sizeof(buf);

socketpair(AF_LOCAL, SOCK_DGRAM, 0, fds);

if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) == -1) {
perror(“setsockopt”);
return 1;
}

buf[0] = ‘a’;

if (send(fds[0], buf, sizeof(buf), 0) == -1) {
perror(“send”);
return 1;
}

if (recv(fds[1], &c, 1, 0) == -1) {
perror(“recv”);
return 1;
}

printf("%c\n", c);

return 0;
}

Igor Kovalenko <kovalenko@attbi.com> wrote:

Thanks Sean, it works of course.

I actually thought of using that too, but then I turned to docs (for
setsockopt) and it said: ‘the system imposes an absolute limit on those
values and defaults to at least 16K’. So if it defaults to 16K, how come
it did not like anything above 2k?

Docs error?

Yep. 16k for tcp sockets.

-seanb