[SOLVED] using AF_UNIX SOCK_DGRAM socket to communicate between one server and multi clients?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
using AF_UNIX SOCK_DGRAM socket to communicate between one server and multi clients?
Currently I use a link list on server to store all clients' sockaddr_un, and loop the link list when server needs to send msg to all clients.
I have googled for a long time to find a method which doesn't need link list and loop, but I have not find the method I expected.
Today I try binding two clients to same sun_path,
server.c:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#define SERVER_SUN_PATH "/tmp/server_sun_path.0"
#define CLIENT_SUN_PATH "/tmp/client_sun_path.0"
static int Init();
static int Deinit();
static int MsgLoop();
static int serverSock = -1;
int main(int argc, char *argv[])
{
int ret = 0;
ret = Init();
if (!ret)
{
ret = MsgLoop();
}
Deinit();
printf("%s: ret=%d\n", __FUNCTION__, ret);
return ret;
}
static int Init()
{
int ret = 0;
const struct sockaddr_un serverSockaddr = {AF_UNIX, SERVER_SUN_PATH};
int optval = 1;
serverSock = socket(AF_UNIX, SOCK_DGRAM, 0);
if (-1 == serverSock)
{
printf("%s: ERROR! socket: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
if (!ret && unlink(SERVER_SUN_PATH) && ENOENT != errno)
{
printf("%s: ERROR! unlink: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
//if (!ret && -1 == setsockopt(serverSock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(int))) {
// printf("%s: ERROR! setsockopt: %s\n", __FUNCTION__, strerror(errno));
// ret = -1;
//}
if (!ret && bind(serverSock, (struct sockaddr *)&serverSockaddr, sizeof(struct sockaddr_un)))
{
printf("%s: ERROR! bind: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
if (0 != ret)
{
Deinit();
}
return ret;
}
static int Deinit()
{
int ret = 0;
if (-1 != serverSock)
{
if (-1 == close(serverSock))
{
printf("%s: ERROR! close: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
}
serverSock = -1;
if (unlink(SERVER_SUN_PATH) && ENOENT != errno)
{
printf("%s: ERROR! unlink: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
return ret;
}
static int MsgLoop()
{
ssize_t sentSize = 0;
unsigned char buf[4] = {0x4, 0x3, 0x2, 0x1};
const struct sockaddr_un clientSockaddr = {AF_UNIX, CLIENT_SUN_PATH};
int ret = 0;
while (!ret)
{
sentSize = sendto(serverSock, buf, sizeof(buf), 0,
(struct sockaddr *)&clientSockaddr, sizeof(struct sockaddr_un));
if (-1 == sentSize && ECONNREFUSED != errno && ENOENT != errno)
{
printf("%s: ERROR! sendto: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
printf("sent %d bytes\n", sentSize);
sleep(1);
}
return ret;
}
client.c:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#define SERVER_SUN_PATH "/tmp/server_sun_path.0"
#define CLIENT_SUN_PATH "/tmp/client_sun_path.0"
static int Init();
static int Deinit();
static int MsgLoop();
static int clientSock = -1;
int main(int argc, char *argv[])
{
int ret = 0;
ret = Init();
if (!ret)
{
ret = MsgLoop();
}
Deinit();
printf("%s: ret=%d\n", __FUNCTION__, ret);
return ret;
}
static int Init()
{
int ret = 0;
const struct sockaddr_un clientSockaddr = {AF_UNIX, CLIENT_SUN_PATH};
int optval = 1;
clientSock = socket(AF_UNIX, SOCK_DGRAM, 0);
if (-1 == clientSock)
{
printf("%s: ERROR! socket: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
if (!ret && unlink(CLIENT_SUN_PATH) && ENOENT != errno)
{
printf("%s: ERROR! unlink: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
//if (!ret && -1 == setsockopt(clientSock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int))) {
// printf("%s: ERROR! setsockopt: %s\n", __FUNCTION__, strerror(errno));
// ret = -1;
//}
if (!ret && bind(clientSock, (struct sockaddr *)&clientSockaddr, sizeof(struct sockaddr_un)))
{
printf("%s: ERROR! bind: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
if (0 != ret)
{
Deinit();
}
return ret;
}
static int Deinit()
{
int ret = 0;
if (-1 != clientSock)
{
if (-1 == close(clientSock))
{
printf("%s: ERROR! close: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
}
clientSock = -1;
if (unlink(CLIENT_SUN_PATH) && ENOENT != errno)
{
printf("%s: ERROR! unlink: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
return ret;
}
static int MsgLoop()
{
ssize_t recvedSize = 0;
unsigned char buf[4];
struct sockaddr_un serverSockaddr;
socklen_t serverSockaddrLen;
int ret = 0;
int i = 0;
while (!ret)
{
memset(buf, 0x00, sizeof(buf));
serverSockaddrLen = sizeof(struct sockaddr_un);
recvedSize = recvfrom(clientSock, buf, sizeof(buf), 0,
(struct sockaddr *)&serverSockaddr, &serverSockaddrLen);
if (-1 == recvedSize)
{
printf("%s: ERROR! recvfrom: %s\n", __FUNCTION__, strerror(errno));
ret = -1;
}
printf("received %d bytes: ", recvedSize);
for (i = 0; i < recvedSize; i++) {
printf("%02x,", buf[i]);
}
printf("\n");
}
return ret;
}
I compile, run server, run client, and open another terminal and run a second client,
When the second client started, the first running client blocks on recvfrom, the second client is receiving msg.
Using setsockopt doesn't change any thing.
Maybe binding two clients to same sun_path is not workable.
My question is: what's the best way of using AF_UNIX SOCK_DGRAM socket to communicate between one server and multiple clients?
I think one of us doesn't understand how server/client architecture works.
Honestly, I'm not familiar with server/client architecture.
I just want to know: what's the best way of sending a same message from one process to several other processes, using AF_UNIX SOCK_DGRAM socket.
Like broadcast, but unix domain datagram socket doesn't support broadcast.
The server shouldn't send anything before a client asks it to do so.
But, a process using UDP socket can do broadcast even there is no receiver process.
I want to use unix domain datagram socket to do something like UDP broadcast.
Quote:
Originally Posted by NevemTeve
Every client has to have an unique address.
If each client has an unique address (for unix domain datagram socket address is filename), how can I send a same message to all clients simultaneously.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.