nbeng

a non-blocking client/server engine
git clone git://git.2f30.org/nbeng
Log | Files | Refs | README

commit 90e042484d278970be026777d54b81661efd3938
parent 46f2ebf533f0afd10fb2563fc98fb343abba25b5
Author: dsp <dsp@2f30.org>
Date:   Thu, 14 Jun 2012 20:11:53 +0300

implemented server logic

Diffstat:
Mnbeng.c | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 108 insertions(+), 32 deletions(-)

diff --git a/nbeng.c b/nbeng.c @@ -34,7 +34,8 @@ usage(const char *s) /* connect to in port port and store the fds in the context */ static void -connectit(concontxt *c, char *to, char *port) { +connectit(concontxt *c, char *to, char *port) +{ struct addrinfo cli_hints, *cli_servinfo, *p0; int rv, cli_sockfd; if ((c == NULL) || (to == NULL) || (port == NULL)) @@ -60,6 +61,104 @@ connectit(concontxt *c, char *to, char *port) { c->clinfo = cli_servinfo; } +static void +serveit(concontxt *c, char *port) +{ + struct addrinfo srv_hints, *srv_servinfo, *p0; + int rv, srv_sockfd,optval; + memset(&srv_hints, 0, sizeof(srv_hints)); + srv_hints.ai_family = AF_INET; + srv_hints.ai_socktype = SOCK_DGRAM; + srv_hints.ai_flags = AI_PASSIVE; + rv = getaddrinfo(NULL, port, &srv_hints, &srv_servinfo); + if (rv) + errx(1, "getaddrinfo: %s", gai_strerror(rv)); + for(p0 = srv_servinfo; p0; p0 = p0->ai_next) { + srv_sockfd = socket(p0->ai_family, p0->ai_socktype, + p0->ai_protocol); + if (srv_sockfd < 0) + continue; + optval = 1; + rv = setsockopt(srv_sockfd, SOL_SOCKET, + SO_REUSEADDR, &optval, sizeof(optval)); + if (rv < 0) { + close(srv_sockfd); + warn("setsockopt"); + continue; + } + if (bind(srv_sockfd, p0->ai_addr, p0->ai_addrlen) < 0) { + close(srv_sockfd); + warn("bind"); + continue; + } + break; + } + if (!p0) + errx(1, "failed to bind socket"); + /* register them to the context */ + c->srvfd = srv_sockfd; + c->srvinfo = srv_servinfo; +} + +static void +stdinputdata(concontxt *con) +{ char *inbuf = NULL, *linbuf = NULL; + ssize_t inbufln; + /* deal with input data */ + inbuf = fgetln(stdin, &inbufln); + if (inbuf[inbufln - 1] == '\n') + inbuf[inbufln - 1] = '\0'; + else { + /* EOF without EOL, + copy and add the NULL */ + if ((linbuf = malloc(inbufln + 1)) + == NULL) { + warnx("linbuf alloc failed"); + goto freex; + } + memcpy(linbuf, inbuf, inbufln); + linbuf[inbufln] = '\0'; + inbuf = linbuf; + } + if ((strncmp(inbuf, "Q", 2) == 0)) + goto freex; + printf("got msg: %s , sending it\n", inbuf); + sendto(con->clifd, inbuf, inbufln, 0, + con->clinfo->ai_addr, + con->clinfo->ai_addrlen); + fflush(stdout); + /* free the buf */ +freex: + if(linbuf != NULL) + free(linbuf); +} + +static void +srvinputdata(concontxt *con) +{ + ssize_t bytes; + int ret; + char host[NI_MAXHOST]; + char buf[512]; + socklen_t addr_len; + struct sockaddr_storage their_addr; + addr_len = sizeof(their_addr); + bytes = recvfrom(con->srvfd, buf, + sizeof(buf), MSG_DONTWAIT, + (struct sockaddr *)&their_addr, + &addr_len); + if (bytes > 0) { + ret = getnameinfo((struct sockaddr *)&their_addr, + addr_len, host, + sizeof(host), NULL, 0, 0); + if (ret < 0) { + warn("getnameinfo"); + snprintf(host, sizeof(host), "unknown"); + } + printf("Received %zd bytes from %s that read: %s \n", bytes, host, buf); + } +} + int main(int argc, char *argv[]) { @@ -70,8 +169,6 @@ main(int argc, char *argv[]) fd_set rsocks; int highsock, readsocks; struct timeval timeout; - char *inbuf = NULL, *linbuf = NULL; - ssize_t inbufln; concontxt *con = (concontxt *) malloc(sizeof (concontxt)); while ((c = getopt(argc, argv, "hs")) != -1) { switch (c) { @@ -96,12 +193,15 @@ main(int argc, char *argv[]) } /* connect to the host */ connectit(con, argv[0], argv[1]); + /* prepare the server socket */ + serveit(con, argv[2]); /* XXX: this should change when we add the srv fd */ - highsock = recfd; + highsock = con->srvfd; /* these are the sockets for reading (stdin + server fd) */ while (1) { FD_ZERO(&rsocks); FD_SET(recfd, &rsocks); + FD_SET(con->srvfd, &rsocks); timeout.tv_sec = 1; timeout.tv_usec = 0; readsocks = select(highsock + 1, &rsocks, (fd_set *)0, @@ -116,32 +216,10 @@ main(int argc, char *argv[]) fflush(stdout); } else { if (FD_ISSET(recfd, &rsocks)) { - /* deal with input data */ - inbuf = fgetln(stdin, &inbufln); - if (inbuf[inbufln - 1] == '\n') - inbuf[inbufln - 1] = '\0'; - else { - /* EOF without EOL, - copy and add the NULL */ - if ((linbuf = malloc(inbufln + 1)) - == NULL) { - warnx("linbuf alloc failed"); - goto freex; - } - memcpy(linbuf, inbuf, inbufln); - linbuf[inbufln] = '\0'; - inbuf = linbuf; - } - if ((strncmp(inbuf, "Q", 2) == 0)) - goto freex; - printf("got msg: %s , sending it\n", inbuf); - sendto(con->clifd, inbuf, inbufln, 0, - con->clinfo->ai_addr, - con->clinfo->ai_addrlen); - fflush(stdout); - /* free the buf */ - if(linbuf != NULL) - free(linbuf); + stdinputdata(con); + } + if (FD_ISSET(con->srvfd,&rsocks)) { + srvinputdata(con); } } } @@ -151,7 +229,5 @@ freex: close(con->clifd); free(con); } - if (inbuf != NULL) - free(inbuf); return (0); }