Archived
3
0

pongd fonctionnel

This commit is contained in:
Philippe PITTOLI 2016-12-23 01:33:52 +01:00
parent 9e2a27cb20
commit 7a9101faf1
10 changed files with 342 additions and 138 deletions

View File

@ -69,6 +69,14 @@ int srv_close (struct service *srv)
int srv_close_proc (struct process *p) int srv_close_proc (struct process *p)
{ {
// struct msg m_ack_dis;
// memset (&m_ack_dis, 0, sizeof (struct msg));
// m_ack_dis.type = MSG_TYPE_ACK_DIS;
// if (msg_write (p->proc_fd, &m_ack_dis) < 0) {
// handle_err ("srv_close_proc", "msg_write < 0");
// }
return usock_close (p->proc_fd); return usock_close (p->proc_fd);
} }
@ -128,6 +136,7 @@ int app_connection (int argc, char **argv, char **env
return 0; return 0;
} }
// send a DIS message then close the socket
int app_close (struct service *srv) int app_close (struct service *srv)
{ {
struct msg m; struct msg m;
@ -137,6 +146,14 @@ int app_close (struct service *srv)
handle_err ("app_close", "msg_write < 0"); handle_err ("app_close", "msg_write < 0");
} }
// if (msg_read (srv->service_fd, &m) < 0) {
// handle_err ("app_close", "msg_read < 0");
// }
// if (m.type != MSG_TYPE_ACK) {
// handle_err ("app_close", "msg received != ACK");
// }
return usock_close (srv->service_fd); return usock_close (srv->service_fd);
} }
@ -165,8 +182,14 @@ int app_write (struct service *srv, const struct msg *m)
*/ */
int srv_select (struct array_proc *ap, struct service *srv int srv_select (struct array_proc *ap, struct service *srv
, struct process **proc) , struct array_proc *proc)
{ {
assert (ap != NULL);
assert (proc != NULL);
// delete previous read process array
array_proc_free (proc);
int i, j; int i, j;
/* master file descriptor list */ /* master file descriptor list */
fd_set master; fd_set master;
@ -190,7 +213,10 @@ int srv_select (struct array_proc *ap, struct service *srv
/* keep track of the biggest file descriptor */ /* keep track of the biggest file descriptor */
fdmax = getMaxFd(ap) > srv->service_fd ? getMaxFd(ap) : srv->service_fd; fdmax = getMaxFd(ap) > srv->service_fd ? getMaxFd(ap) : srv->service_fd;
while (1) { int is_listener = 0;
do {
// printf ("loop srv_select main_loop\n");
readf = master; readf = master;
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) { if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
perror("select"); perror("select");
@ -199,20 +225,27 @@ int srv_select (struct array_proc *ap, struct service *srv
/*run through the existing connections looking for data to be read*/ /*run through the existing connections looking for data to be read*/
for (i = 0; i <= fdmax; i++) { for (i = 0; i <= fdmax; i++) {
// printf ("loop srv_select inner loop\n");
if (FD_ISSET(i, &readf)) { if (FD_ISSET(i, &readf)) {
if (i == listener) { if (i == listener) {
return CONNECTION; is_listener = 1;
} else { } else {
for(j = 0; j < ap->size; j++) { for(j = 0; j < ap->size; j++) {
// printf ("loop srv_select inner inner loop\n");
if(i == ap->tab_proc[j]->proc_fd ) { if(i == ap->tab_proc[j]->proc_fd ) {
*proc = ap->tab_proc[j]; add_proc (proc, ap->tab_proc[j]);
}
}
}
}
}
} while (0);
if (proc->size > 0 && is_listener)
return CON_APP;
if (proc->size > 0)
return APPLICATION; return APPLICATION;
} return CONNECTION;
}
}
}
}
}
} }
/*calculer le max filedescriptor*/ /*calculer le max filedescriptor*/

View File

@ -20,6 +20,7 @@
#define CONNECTION 0 #define CONNECTION 0
#define APPLICATION 1 #define APPLICATION 1
#define CON_APP 2
struct service { struct service {
unsigned int version; unsigned int version;
@ -42,7 +43,7 @@ int srv_accept (struct service *srv, struct process *p);
int srv_read (const struct process *, struct msg *m); int srv_read (const struct process *, struct msg *m);
int srv_write (const struct process *, const struct msg *m); int srv_write (const struct process *, const struct msg *m);
int srv_select(struct array_proc *, struct service *, struct process **); int srv_select (struct array_proc *, struct service *, struct array_proc *);
int getMaxFd(struct array_proc *); int getMaxFd(struct array_proc *);

View File

@ -10,6 +10,7 @@
#define MSG_TYPE_ERR 3 #define MSG_TYPE_ERR 3
#define MSG_TYPE_ACK 4 #define MSG_TYPE_ACK 4
#define MSG_TYPE_DATA 5 #define MSG_TYPE_DATA 5
#define MSG_TYPE_ACK_DIS 6
struct msg { struct msg {
char type; char type;

View File

@ -52,25 +52,36 @@ int add_proc (struct array_proc *aproc, struct process *p)
int del_proc (struct array_proc *aproc, struct process *p) int del_proc (struct array_proc *aproc, struct process *p)
{ {
assert(aproc != NULL); assert(aproc != NULL);
assert(aproc->tab_proc != NULL);
assert(p != NULL); assert(p != NULL);
if (aproc->tab_proc == NULL) {
return -1;
}
int i; int i;
for (i = 0; i < aproc->size; i++) { for (i = 0; i < aproc->size; i++) {
if (aproc->tab_proc[i] == p) { if (aproc->tab_proc[i] == p) {
aproc->tab_proc[i] = aproc->tab_proc[aproc->size-1]; aproc->tab_proc[i] = aproc->tab_proc[aproc->size-1];
aproc->size--; aproc->size--;
if (aproc->size == 0) {
array_proc_free (aproc);
}
else {
aproc->tab_proc = realloc(aproc->tab_proc aproc->tab_proc = realloc(aproc->tab_proc
, sizeof(struct process) * aproc->size); , sizeof(struct process) * aproc->size);
if (aproc->tab_proc == NULL) { if (aproc->tab_proc == NULL) {
return -1; return -2;
} }
}
return 0; return 0;
} }
} }
return -2; return -3;
} }
void process_print (struct process *p) void process_print (struct process *p)
@ -91,6 +102,9 @@ void array_proc_print (struct array_proc *ap)
void array_proc_free (struct array_proc *ap) void array_proc_free (struct array_proc *ap)
{ {
if (ap->tab_proc != NULL) if (ap->tab_proc != NULL) {
free (ap->tab_proc), ap->tab_proc = NULL; free (ap->tab_proc);
ap->tab_proc = NULL;
}
ap->size = 0;
} }

View File

@ -12,11 +12,9 @@ struct array_proc {
int size; int size;
}; };
// TODO
// tout revoir
int add_proc (struct array_proc *, struct process *); int add_proc (struct array_proc *, struct process *);
int del_proc(struct array_proc *, struct process *); int del_proc (struct array_proc *aproc, struct process *p);
void array_proc_print (struct array_proc *); void array_proc_print (struct array_proc *);
void array_proc_free (struct array_proc *); void array_proc_free (struct array_proc *);

View File

@ -10,8 +10,8 @@
int usock_send (const int fd, const char *buf, const int msize) int usock_send (const int fd, const char *buf, const int msize)
{ {
print_hexa ("msg send", (unsigned char *)buf, msize); // print_hexa ("msg send", (unsigned char *)buf, msize);
fflush(stdout); // fflush(stdout);
int ret = 0; int ret = 0;
//printf ("%ld bytes to write\n", msize); //printf ("%ld bytes to write\n", msize);
@ -53,8 +53,8 @@ int usock_recv (const int fd, char **buf, size_t *msize)
return ret; return ret;
} }
*msize = (size_t) ret; *msize = (size_t) ret;
print_hexa ("msg recv", (unsigned char *)*buf, *msize); // print_hexa ("msg recv", (unsigned char *)*buf, *msize);
fflush(stdout); // fflush(stdout);
return ret; return ret;
} }

View File

@ -9,6 +9,10 @@ TESTS=$(addsuffix .test, $(EXEC))
all: $(SOURCES) $(EXEC) all: $(SOURCES) $(EXEC)
test:
rm /tmp/ipc/pongd-0-0
./pongd.bin
$(EXEC): $(OBJECTS) $(CFILES) $(EXEC): $(OBJECTS) $(CFILES)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $@.c -lcbor -o $@.bin $(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $@.c -lcbor -o $@.bin

View File

@ -1,108 +0,0 @@
#include "../../core/communication.h"
#include <sys/socket.h>
#include <sys/un.h>
#include "../../core/process.h"
#include <unistd.h>
#define PONGD_SERVICE_NAME "pongd"
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
/*
* main loop
*
* opens the application pipes,
* reads then writes the same message,
* then closes the pipes
*/
void main_loop (struct service *srv)
{
size_t msize = BUFSIZ;
char *buf = NULL;
if ( (buf = malloc (BUFSIZ)) == NULL) {
handle_error ("malloc");
}
memset (buf, 0, BUFSIZ);
int i,ret, cpt = 0;
struct array_proc ap;
memset(&ap, 0, sizeof(struct array_proc));
struct process *p2 = malloc(sizeof(struct process));
while(cpt < 5) {
ret = srv_select(&ap, srv, &p2);
if (ret == CONNECTION) {
struct process *p = malloc(sizeof(struct process));
memset(p, 0, sizeof(struct process));
if (srv_accept (srv, p) < 0) {
handle_error("srv_accept < 0");
}else {
printf("new connection\n");
}
if (add_proc(&ap, p) < 0) {
handle_error("add_proc < 0");
}
cpt++;
} else {
if (srv_read(p2, &buf, &msize) < 0) {
handle_error("srv_read < 0");
}
if (srv_write (p2, buf, msize) < 0) {
handle_error("srv_write < 0");
}
}
}
for (i = 0; i < ap.size; i++) {
if (srv_close_proc (ap.tab_proc[i]) < 0) {
handle_error( "srv_close_proc < 0");
}
}
}
/*
* service ping-pong
*
* 1. creates the named pipe /tmp/<service>, then listens
* 2. opens the named pipes in & out
* 3. talks with the (test) program
* 4. closes the test program named pipes
* 5. removes the named pipe /tmp/<service>
*/
int main(int argc, char * argv[], char **env)
{
struct service srv;
memset (&srv, 0, sizeof (struct service));
srv.index = 0;
srv.version = 0;
unlink("/tmp/ipc/pongd-0-0");
if (srv_init (argc, argv, env, &srv, PONGD_SERVICE_NAME) < 0) {
handle_error("srv_init < 0");
return EXIT_FAILURE;
}
printf ("Listening on %s.\n", srv.spath);
printf("MAIN: server created\n" );
// the service will loop until the end of time, a specific message, a signal
main_loop (&srv);
// the application will shut down, and remove the service named pipe
if (srv_close (&srv) < 0) {
handle_error("srv_close < 0");
}
return EXIT_SUCCESS;
}

117
pong/app/pong.c Normal file
View File

@ -0,0 +1,117 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../../core/msg.h"
#include "../../core/error.h"
#include "../../core/communication.h"
#define MSG "coucou"
#define SERVICE_NAME "pongd"
void non_interactive (int argc, char *argv[], char *env[])
{
struct msg m;
memset (&m, 0, sizeof (struct msg));
struct service srv;
memset (&srv, 0, sizeof (struct service));
// index and version should be filled
srv.index = 0;
srv.version = 0;
// init service
if (app_connection (argc, argv, env, &srv, SERVICE_NAME, NULL, 0) < 0) {
handle_err("main", "srv_init < 0");
exit (EXIT_FAILURE);
}
printf ("msg to send: %s\n", MSG);
msg_format_data (&m, MSG, strlen(MSG) +1);
printf ("msg to send in the client: ");
print_msg (&m);
if (app_write (&srv, &m) < 0) {
handle_err("main", "app_write < 0");
exit (EXIT_FAILURE);
}
msg_free (&m);
if (app_read (&srv, &m) < 0) {
handle_err("main", "app_read < 0");
exit (EXIT_FAILURE);
}
printf ("msg recv: %s\n", m.val);
msg_free (&m);
if (app_close (&srv) < 0) {
handle_err("main", "app_close < 0");
exit (EXIT_FAILURE);
}
}
void interactive (int argc, char *argv[], char *env[])
{
struct msg m;
memset (&m, 0, sizeof (struct msg));
struct service srv;
memset (&srv, 0, sizeof (struct service));
char buf[BUFSIZ];
memset (buf, 0, BUFSIZ);
int n;
// index and version should be filled
srv.index = 0;
srv.version = 0;
// init service
if (app_connection (argc, argv, env, &srv, SERVICE_NAME, NULL, 0) < 0) {
handle_err ("main", "srv_init < 0");
exit (EXIT_FAILURE);
}
while (1) {
printf ("msg to send: ");
fflush (stdout);
n = read (0, buf, BUFSIZ);
if (n == 0 || strncmp (buf, "exit", 4) == 0)
break;
msg_format_data (&m, buf, strlen(buf) +1);
memset (buf, 0, BUFSIZ);
// print_msg (&m);
if (app_write (&srv, &m) < 0) {
handle_err("main", "app_write < 0");
exit (EXIT_FAILURE);
}
msg_free (&m);
if (app_read (&srv, &m) < 0) {
handle_err("main", "app_read < 0");
exit (EXIT_FAILURE);
}
printf ("msg recv: %s", m.val);
msg_free (&m);
}
if (app_close (&srv) < 0) {
handle_err("main", "app_close < 0");
exit (EXIT_FAILURE);
}
}
int main (int argc, char *argv[], char *env[])
{
if (argc == 1)
non_interactive (argc, argv, env);
else
interactive (argc, argv, env);
return EXIT_SUCCESS;
}

144
pong/app/pongd.c Normal file
View File

@ -0,0 +1,144 @@
#include "../../core/communication.h"
#include "../../core/process.h"
#include "../../core/error.h"
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#define PONGD_SERVICE_NAME "pongd"
int cpt = 0;
void handle_new_connection (struct service *srv, struct array_proc *ap)
{
struct process *p = malloc(sizeof(struct process));
memset(p, 0, sizeof(struct process));
if (srv_accept (srv, p) < 0) {
handle_error("srv_accept < 0");
} else {
printf("new connection\n");
}
if (add_proc (ap, p) < 0) {
handle_error("add_proc < 0");
}
cpt++;
printf ("%d client(s)\n", cpt);
}
void handle_new_msg (struct array_proc *ap, struct array_proc *proc_to_read)
{
struct msg m;
memset (&m, 0, sizeof (struct msg));
int i;
for (i = 0; i < proc_to_read->size; i++) {
// printf ("loop handle_new_msg\n");
if (srv_read (proc_to_read->tab_proc[i], &m) < 0) {
handle_error("srv_read < 0");
}
// close the process then delete it from the process array
if (m.type == MSG_TYPE_DIS) {
cpt--;
printf ("disconnection => %d client(s) remaining\n", cpt);
if (srv_close_proc (proc_to_read->tab_proc[i]) < 0)
handle_error( "srv_close_proc < 0");
if (del_proc (ap, proc_to_read->tab_proc[i]) < 0)
handle_error( "del_proc < 0");
if (del_proc (proc_to_read, proc_to_read->tab_proc[i]) < 0)
handle_err( "handle_new_msg", "del_proc < 0");
i--;
continue;
}
printf ("new message : %s", m.val);
if (srv_write (proc_to_read->tab_proc[i], &m) < 0) {
handle_error("srv_write < 0");
}
}
}
/*
* main loop
*
* accept new application connections
* read a message and send it back
* close a connection if MSG_TYPE_DIS received
*/
void main_loop (struct service *srv)
{
int i, ret = 0;
struct array_proc ap;
memset(&ap, 0, sizeof(struct array_proc));
struct array_proc proc_to_read;
memset(&proc_to_read, 0, sizeof(struct array_proc));
while(1) {
ret = srv_select (&ap, srv, &proc_to_read);
// printf ("on peut lire ces process:\n");
// array_proc_print (&proc_to_read);
// printf ("-- \n\n");
if (ret == CONNECTION) {
handle_new_connection (srv, &ap);
} else if (ret == APPLICATION) {
handle_new_msg (&ap, &proc_to_read);
} else { // both new connection and new msg from at least one client
handle_new_connection (srv, &ap);
handle_new_msg (&ap, &proc_to_read);
}
array_proc_free (&proc_to_read);
}
for (i = 0; i < ap.size; i++) {
if (srv_close_proc (ap.tab_proc[i]) < 0) {
handle_error( "srv_close_proc < 0");
}
}
}
/*
* service ping-pong
*
* 1. creates the named pipe /tmp/<service>, then listens
* 2. opens the named pipes in & out
* 3. talks with the (test) program
* 4. closes the test program named pipes
* 5. removes the named pipe /tmp/<service>
*/
int main(int argc, char * argv[], char **env)
{
struct service srv;
memset (&srv, 0, sizeof (struct service));
srv.index = 0;
srv.version = 0;
// unlink("/tmp/ipc/pongd-0-0");
if (srv_init (argc, argv, env, &srv, PONGD_SERVICE_NAME) < 0) {
handle_error("srv_init < 0");
return EXIT_FAILURE;
}
printf ("Listening on %s.\n", srv.spath);
printf("MAIN: server created\n" );
// the service will loop until the end of time, a specific message, a signal
main_loop (&srv);
// the application will shut down, and remove the service named pipe
if (srv_close (&srv) < 0) {
handle_error("srv_close < 0");
}
return EXIT_SUCCESS;
}