-
Notifications
You must be signed in to change notification settings - Fork 0
/
bus_client.c
153 lines (133 loc) · 4.87 KB
/
bus_client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_GREEN "\x1b[32m"
#define ANSI_COLOR_YELLOW "\x1b[33m"
#define ANSI_COLOR_BLUE "\x1b[34m"
#define ANSI_COLOR_MAGENTA "\x1b[35m"
#define ANSI_COLOR_CYAN "\x1b[36m"
#define ANSI_COLOR_RESET "\x1b[0m"
#define BUF_SIZE 1024
int server; /* socket du serveur en attente de connection */
static inline int max(int x, int y) {
return x > y ? x : y;
}
void hdlr_fin(int sig) {
printf("Reception du signal %d. Arret du client !\n", sig);
close(server);
exit(EXIT_SUCCESS);
}
int main(int argc, char **argv) {
struct sockaddr_un a;
char buffer[BUF_SIZE];
int r;
ssize_t rd_sz, wr_sz;
if (argc != 2) {
fprintf(stderr,
"Utilisation:\n\t%s <Unix socket path>\n", argv[0]);
exit(EXIT_FAILURE);
}
/*
* The SIGPIPE signal will be received if the peer has gone away
* and an attempt is made to write data to the peer. Ignoring this
* signal causes the write operation to receive an EPIPE error.
* Thus, the user is informed about what happened.
*/
signal(SIGPIPE, SIG_IGN);
/* pour une terminaison propre sur QUIT TERM INT SEGV... */
signal(SIGQUIT, hdlr_fin);
signal(SIGTERM, hdlr_fin);
signal(SIGINT, hdlr_fin);
signal(SIGSEGV, hdlr_fin);
/* creation de la socket client */
if ((server = socket(PF_UNIX, SOCK_SEQPACKET, 0)) < 0) {
perror("socket()");
exit(EXIT_FAILURE);
}
/* preparation de la structure d'adresse de la socket serveur sur
laquelle on va se connecter */
memset(&a, 0, sizeof (a)); /* nettoyage de la structure */
a.sun_family = AF_UNIX; /* famille de l'adresse */
strncpy(a.sun_path, argv[1], sizeof (a.sun_path) - 1 /* 108 UNIX_PATH_MAX*/);
/* Connexion au serveur */
if (connect(server, (struct sockaddr *) &a, sizeof (a)) < 0) {
perror("connect()");
close(server);
exit(EXIT_FAILURE);
}
/* le corps du programme */
printf(ANSI_COLOR_GREEN "Le client est accroche au bus." ANSI_COLOR_RESET "\n");
for (;;) {
int nfds = 0;
fd_set rd_set; /* Cree le catalogue des sockets interessantes en lecture */
//fd_set wd_set;
//fd_set ed_set;
/* Nettoyage de ce catalogue */
FD_ZERO(&rd_set);
/* On y place les descripteurs interessants en lecture */
/* On s'interesse a la socket du serveur */
FD_SET(server, &rd_set);
nfds = max(nfds, server);
/* ajoute STDIN */
FD_SET(STDIN_FILENO, &rd_set);
nfds = max(nfds, STDIN_FILENO); /* pour le principe */
struct timeval tv;
/* Attends jusqu’à 5 secondes. */
tv.tv_sec = 5;
tv.tv_usec = 0;
/* Se bloque en attente de quelque chose d'interessant */
r = select(nfds + 1, &rd_set, NULL, NULL, &tv);
if (r == -1 && errno == EINTR)
continue;
if (r < 0) {
perror("select()");
exit(EXIT_FAILURE);
}
if (FD_ISSET(server, &rd_set)) { /* evenement socket */
/* Hypothese : on lit le paquet d'un seul coup !
Prevoir une buffer assez grand */
rd_sz = recv(server, buffer, BUF_SIZE, MSG_WAITALL);
if (rd_sz < 0) {
perror("recv()");
close(server);
exit(EXIT_FAILURE);
} else if (rd_sz == 0) {
printf(ANSI_COLOR_RED "Le bus est arrete !" ANSI_COLOR_RESET "\n");
exit(EXIT_SUCCESS);
} else if (rd_sz > 0) {
printf("Reception de %d octets : [" ANSI_COLOR_BLUE "\n", rd_sz);
/* Ecriture sur le staandard de sortie de ce qui est recu du serveur */
write(STDOUT_FILENO, buffer, rd_sz);
printf(ANSI_COLOR_RESET "]\n");
}
}
if (FD_ISSET(STDIN_FILENO, &rd_set)) { /* evenement stdin */
/* Hypothese : on lit le paquet d'un seul coup !
Prevoir une buffer assez grand */
fgets(buffer, BUF_SIZE, stdin);
rd_sz = strlen(buffer);
/* envoi vers le serveur */
wr_sz = send(server, buffer, rd_sz, 0);
if (wr_sz < 0) {
perror("send()");
close(server);
exit(EXIT_FAILURE);
} else if (wr_sz == 0) {
printf(ANSI_COLOR_RED "Le bus est arrete !" ANSI_COLOR_RESET "\n");
exit(EXIT_SUCCESS);
} else if (wr_sz > 0) {
printf(ANSI_COLOR_GREEN "Envoie de %d octets" ANSI_COLOR_RESET "\n", wr_sz);
}
}
}
/* superflu apres la boucle infinie */
exit(EXIT_SUCCESS);
}