How to make a "careless" socket?
I need to have a socket (or other method of IPC) with following behaviour:
writer needs to be able to send data to socket without blocking
if there is no one listening, the data are discarded
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 开发者_JAVA技巧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").
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 fromrecvfrom()
Client side:
- bind port
- send packets to server with
sendto()
- read replies with
recvfrom()
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.
精彩评论