Skip to content

Instantly share code, notes, and snippets.

@vthanki
Created May 12, 2016 20:05
Show Gist options
  • Save vthanki/8405c9cd4a09d3a0b73bf876b2635ad4 to your computer and use it in GitHub Desktop.
Save vthanki/8405c9cd4a09d3a0b73bf876b2635ad4 to your computer and use it in GitHub Desktop.
Unix Socket example, modified to see the behavior of poll() when remote socket is closed before recv() call is made on server.
/*
* Code borrowed from http://beej.us/guide/bgipc/output/html/multipage/unixsock.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "/tmp/unix.socket.ex"
int main(void)
{
int s, t, len;
struct sockaddr_un remote;
char str[100];
char *hello = "hello 123123123";
if ((s = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0)) == -1) {
perror("socket");
exit(1);
}
printf("Trying to connect...\n");
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCK_PATH);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if (connect(s, (struct sockaddr *)&remote, len) == -1) {
perror("connect");
exit(1);
}
printf("Connected.\n");
#if 0
while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) {
if (send(s, str, strlen(str), 0) == -1) {
perror("send");
exit(1);
}
if ((t=recv(s, str, 100, 0)) > 0) {
str[t] = '\0';
printf("echo> %s", str);
} else {
if (t < 0) perror("recv");
else printf("Server closed connection\n");
exit(1);
}
}
#else
if (send(s, hello, strlen(hello), 0) < 0)
printf("Send failed\n");
else
printf("data sent\n");
#endif
close(s);
return 0;
}
/*
* Code borrowed from http://beej.us/guide/bgipc/output/html/multipage/unixsock.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <poll.h>
#define SOCK_PATH "/tmp/unix.socket.ex"
int main(void)
{
int s, s2, t, len;
struct sockaddr_un local, remote;
char str[100] = {0};
struct pollfd pfd;
if ((s = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0)) == -1) {
perror("socket");
exit(1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCK_PATH);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(s, (struct sockaddr *)&local, len) == -1) {
perror("bind");
exit(1);
}
if (listen(s, 5) == -1) {
perror("listen");
exit(1);
}
for(;;) {
int done, n;
printf("Waiting for a connection...\n");
t = sizeof(remote);
if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
perror("accept");
exit(1);
}
printf("Connected.\n");
done = 0;
do {
int rc;
printf("Sleeping for 5 seconds, connect the client and exit from client\n");
sleep(5);
pfd.fd = s2;
pfd.events = POLLIN;
rc = poll(&pfd, 1, 15000);
if (!rc) printf("poll timed out\n");
if (rc < 0) printf("poll failed\n");
printf("events: 0x%x\n", pfd.revents);
if (pfd.revents & POLLIN) {
n = recv(s2, str, 100, MSG_PEEK);
printf("There are %d bytes to be read\n", n);
}
// printf("1000 seconds sleep before receive\n");
// sleep (1000);
n = recv(s2, str, 100, 0);
if (n <= 0) {
if (n < 0) perror("recv");
done = 1;
}
printf("data recvd: %s\n", str);
break;
if (!done)
if (send(s2, str, n, 0) < 0) {
perror("send");
done = 1;
}
} while (!done);
close(s2);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment