Srv19
Srv19

Reputation: 3618

How to make a "careless" socket?

I need to have a socket (or other method of IPC) with following behaviour:

  1. writer needs to be able to send data to socket without blocking

  2. if there is no one listening, the data are discarded

  3. as usual, reader needs to be able to connect and recieve those data

What have i done:

created a socked by calling

sock = socket (PF_LOCAL, SOCK_DGRAM, 0); //sock is an integer

binded it with

struct sockaddr_un name;
memset(&name,0,sizeof(struct sockaddr_un));
name.sun_family = AF_LOCAL;
strncpy (name.sun_path, filename, sizeof (name.sun_path)); //filename contains "/cosmos"
bind (sock, (struct sockaddr *) &name, sizeof(struct sockaddr_un));

then made a poll on it

struct pollfd pld;
pld.events = POLLOUT;
pld.fd = sock;
pld.revents=0;

//in loop
poll(&pld,1,50);
if(pld.revents & POLLOUT)
   write(fr,mydata,19);

Tracing outputshows that write is executed (repeatedly). To listen on it i have done:

struct sockaddr_un cos_name;
int cosmos;
char buffer[100];
memset(&cos_name,0,sizeof(struct sockaddr_un));
strncpy (cos_name.sun_path, COSMOS_SOCKET, sizeof (cos_name.sun_path));
memset(buffer,0,100);
cosmos = socket (PF_LOCAL, SOCK_DGRAM, 0);
//check on cosmos being 0
if (connect(cosmos,(struct sockaddr*) &cos_name, sizeof(struct sockaddr_un)) != 0)
{
    printf("Connecting failed: %s.\n",strerror(errno));
    return;
}
printf("Listening successfully started.\n");
//loop
{
    read(cosmos,buffer,100);
    printf("Recieved: %s.\n",buffer);
}

However, "Recieved..." is never printed.

What needs to be changed to achieve desired functionality? What should be the clause on the last loop? (i'm using a simple "run 1000 times now").

Upvotes: 0

Views: 366

Answers (2)

ulidtko
ulidtko

Reputation: 15634

I love to toy with sockets in interactive Python shell, it's very illustrative. See how your problem is basically solved with UDP sockets:

#-- setup receiving on client
>>> from socket import *
>>>
>>> rsock = socket(AF_INET, SOCK_DGRAM)
>>> rsock.bind(("127.0.0.1", 7888))
>>> rsock.recv(100)

Client blocks waiting for data. Good, let's go send something to it!

#-- server
>>> from socket import *
>>> 
>>> sock = socket(AF_INET, SOCK_DGRAM)
>>> sock2.sendto("hello", ("127.0.0.1", 7888))
5
>>>

Ok, message sent. Switch to client console and see 'hello'! ;) Try it out, it's really fun.


By the way, PF_INET is not mandatory, SOCK_DGRAMs work in absolutely the same way with PF_UNIX.

Upvotes: 0

Brian Roach
Brian Roach

Reputation: 76908

Er, I think you need to read up a bit on UDP sockets.

They're connectionless. You just send packets to a destination and hope someone is listening.

On the server side you use recvfrom() to read packets. In order to send a packet back to the client, you use sendto() with the struct sockaddr *src_addr that you passed into your recvfrom() (it's populated with the info for the client that sent the packet you just received).

The client needs to bind a port as well, and use recvfrom() to get packets back from the server.

Server side:

  • bind port
  • read packets with recvfrom()
  • send packets with sendto() back to clients using info returned from recvfrom()

Client side:

  • bind port
  • send packets to server with sendto()
  • read replies with recvfrom()

Upvotes: 8

Related Questions