From 18274274dac64d3ef2174b0782b270bc485f3016 Mon Sep 17 00:00:00 2001 From: Laurent Ghigonis Date: Thu, 29 Nov 2012 07:42:17 +0100 Subject: improve connection handling between server and client. better API. skeletion for packet_decode() --- libglouglou/libglouglou.c | 95 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 13 deletions(-) (limited to 'libglouglou/libglouglou.c') diff --git a/libglouglou/libglouglou.c b/libglouglou/libglouglou.c index a0b85ee..24ba33e 100644 --- a/libglouglou/libglouglou.c +++ b/libglouglou/libglouglou.c @@ -28,8 +28,8 @@ void cb_cli_receive(evutil_socket_t, short, void *); */ struct gg_server * gg_server_start(struct event_base *ev_base, char *ip, int port, - int (*handle_conn)(struct gg_server *, int, struct sockaddr_in *), - int (*handle_packet)(struct gg_server *, struct gg_packet *)) + int (*handle_conn)(struct gg_server *, struct gg_user *), + int (*handle_packet)(struct gg_server *, struct gg_user *, struct gg_packet *)) { struct gg_server *srv; struct sockaddr_in sock_addr; @@ -121,19 +121,39 @@ user_add(struct gg_server *srv, struct sockaddr_in *remote) return usr; } +struct gg_packet * +pkt_decode(char **buf, int *buf_len) +{ + char *p; + int len; + + p = *buf; + len = *buf_len; + + // XXX IN PROGRESS + + *buf = p; + *buf_len = len; + return NULL; +} + void cb_srv_receive(evutil_socket_t fd, short what, void *arg) { struct gg_server *srv; struct gg_user *usr; + struct gg_packet *pkt; struct sockaddr_in remote; + socklen_t remote_len; char buf[16384]; - socklen_t len; - int rv; + char *buf_p; + int buf_len; + int len; srv = arg; - rv = recvfrom(fd, buf, sizeof(buf), 0, - (struct sockaddr *)&remote, &len); - if (rv < 0) { + remote_len = sizeof(struct sockaddr_in); + len = recvfrom(fd, buf, sizeof(buf), 0, + (struct sockaddr *)&remote, &remote_len); + if (len < 0) { printf("libglouglou: cb_srv_receive: recvfrom failed\n"); return; } @@ -141,10 +161,22 @@ void cb_srv_receive(evutil_socket_t fd, short what, void *arg) if (!usr) { usr = user_add(srv, &remote); if (srv->handle_conn) - srv->handle_conn(srv, usr->id, &remote); + srv->handle_conn(srv, usr); printf("srv: New user %d !\n", usr->id); + if (sendto(srv->sock, "", strlen(""), 0, + (struct sockaddr *)&remote, remote_len) == -1) + printf("srv: send failed: %s\n", strerror(errno)); } else { - printf("srv: Incoming data for existing user !\n"); + printf("srv: Incoming data from existing user !\n"); + buf_p = buf; + buf_len = len; + while ((pkt = pkt_decode(&buf_p, &buf_len))) + if (srv->handle_packet) + srv->handle_packet(srv, usr, pkt); + if (buf_len > 0) { + /* XXX store incomplete packet for next recv */ + printf("srv: incomplete packet, dropped %d bytes !\n", buf_len); + } } } @@ -157,7 +189,7 @@ void cb_srv_receive(evutil_socket_t fd, short what, void *arg) */ struct gg_client * gg_client_connect(struct event_base *ev_base, char *ip, int port, - int (*handle_conn)(struct gg_client *, int), + int (*handle_conn)(struct gg_client *), int (*handle_packet)(struct gg_client *, struct gg_packet *)) { struct gg_client *cli; @@ -188,8 +220,9 @@ gg_client_connect(struct event_base *ev_base, char *ip, int port, event_add(ev, NULL); cli->ev = ev; - sendto(s, "", strlen(""), 0, - (struct sockaddr *)&sock_addr, sizeof(struct sockaddr)); + if (sendto(s, "", strlen(""), 0, + (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == -1) + printf("cli: send failed: %s\n", strerror(errno)); return cli; @@ -222,7 +255,43 @@ gg_client_disconnect(struct gg_client *cli) void cb_cli_receive(evutil_socket_t fd, short what, void *arg) { - printf("cli: Incoming data !\n"); + struct gg_client *cli; + struct gg_packet *pkt; + struct sockaddr_in remote; + socklen_t remote_len; + char buf[16384]; + char *buf_p; + int buf_len; + int len; + + cli = arg; + len = recvfrom(fd, buf, sizeof(buf), 0, + (struct sockaddr *)&remote, &remote_len); + if (len < 0) { + printf("libglouglou: cb_cli_receive: recvfrom failed\n"); + return; + } + + switch (cli->status) { + case GG_CLIENT_STATUS_DISCONNECTED: + printf("cli: Connected !\n"); + cli->status = GG_CLIENT_STATUS_CONNECTED; + if (cli->handle_conn) + cli->handle_conn(cli); + break; + case GG_CLIENT_STATUS_CONNECTED: + printf("cli: Incoming data !\n"); + buf_p = buf; + buf_len = len; + while ((pkt = pkt_decode(&buf_p, &buf_len))) + if (cli->handle_packet) + cli->handle_packet(cli, pkt); + if (buf_len > 0) { + /* XXX store incomplete packet for next recv */ + printf("cli: incomplete packet, dropped %d bytes !\n", buf_len); + } + break; + } } /* -- cgit v1.2.3-59-g8ed1b