#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int cnet_init(int port) { int yes=1; int rc; cnet_sfd = socket(AF_INET, SOCK_STREAM, 0); if (cnet_sfd < 0) { perror("socket"); return(-1); } if (setsockopt(cnet_sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) { perror("setsockopt"); return(-1); } cnet_saddr.sin_family = AF_INET; cnet_saddr.sin_addr.s_addr = INADDR_ANY; cnet_saddr.sin_port = htons(port); rc = bind(cnet_sfd, (struct sockaddr *) &cnet_saddr, sizeof(cnet_saddr)); if (rc < 0) { perror("bind"); return(-1); } rc = listen(cnet_sfd, 64); if (rc < 0) { perror("listen"); return(-1); } return(0); } int cnet_accept() { int clen, rc, numfds; fd_set rfds; struct timeval timeout; // set up read fds struct and timeout for select() FD_ZERO(&rfds); FD_SET(cnet_sfd, &rfds); timeout.tv_sec = 300; timeout.tv_usec = 0; numfds = cnet_sfd + 1; rc = select(numfds, &rfds, NULL, NULL, &timeout); if (rc <= 0) { return(-1); } else { clen = sizeof(cnet_caddr); return(accept(cnet_sfd, (struct sockaddr *)&cnet_caddr, &clen)); } } int cnet_close() { close(cnet_sfd); return(0); } int cnet_connect(char *hostname, int port, int *sd) { int sfd, flags, rc, numfds; struct sockaddr_in serv_addr; struct hostent *server; struct timeval timeout; fd_set wfds; sfd = socket(AF_INET, SOCK_STREAM, 0); if (sfd < 0) { perror("socket"); return(-1); } *sd = sfd; server = gethostbyname(hostname); if (server == NULL) { perror("gethostbyname"); return(-1); } // got the socket, figured out the host addr, lets init some variables bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(port); FD_ZERO(&wfds); FD_SET(sfd, &wfds); numfds = sfd + 1; timeout.tv_sec = 2; timeout.tv_usec = 0; flags = fcntl(sfd, F_GETFL); if (flags < 0) { perror("getflags fcntl"); return(-1); } rc = fcntl(sfd, F_SETFL, flags | O_NONBLOCK); if (rc < 0) { perror("nonblock fcntl"); return(-1); } // now that we're non-blocking, this should just go through rc = connect(sfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); /* non blocking version */ /* if (connect(sfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) <= 0) { printf("ERNO: %d\n", errno); if (errno != EINPROGRESS) { perror("connect"); return(-1); } } */ // now we actually wait for the connect to complete rc = select(numfds, NULL, &wfds, NULL, &timeout); if (rc <= 0) { fprintf(stderr, "select timed out on connect\n"); return(-1); } // reset socket to blockin rc = fcntl(sfd, F_SETFL, flags); if (rc < 0) { perror("resetflags fcntl"); return(-1); } return(0); } int cnet_send(int sfd, const void *buf, int bytes) { int rc, writebytes, numfds; fd_set wfds; struct timeval timeout; FD_ZERO(&wfds); FD_SET(sfd, &wfds); numfds = sfd + 1; timeout.tv_sec = 300; timeout.tv_usec = 0; rc = select(numfds, NULL, &wfds, NULL, &timeout); if (rc <= 0) { fprintf(stderr, "ERROR: select timed out in send\n"); return(-1); } rc = send(sfd, buf, bytes, 0); if (rc < 0) { perror("send"); return(-1); } writebytes = rc; return(writebytes); } int cnet_recv(int sfd, void *buf, int bytes) { int rc, readbytes, numfds; fd_set rfds; struct timeval timeout; FD_ZERO(&rfds); FD_SET(sfd, &rfds); numfds = sfd + 1; timeout.tv_sec = 300; timeout.tv_usec = 0; rc = select(numfds, &rfds, NULL, NULL, &timeout); if (rc <= 0) { fprintf(stderr, "ERROR: select timed out in recv\n"); return(-1); } rc = recv(sfd, buf, bytes, 0); if (rc < 0) { perror("recv"); return(-1); } readbytes = rc; return(readbytes); } int cnet_sendbuf(int sfd, const void *buf, int bytes) { int writebytes, rc; writebytes = 0; while(writebytes < bytes) { rc = cnet_send(sfd, buf+writebytes, bytes-writebytes); if (rc <= 0) { return(rc); } writebytes += rc; } return(writebytes); } int cnet_recvbuf(int sfd, void *buf, int bytes) { int readbytes, rc; readbytes = 0; while(readbytes < bytes) { rc = cnet_recv(sfd, buf+readbytes, bytes-readbytes); if (rc <= 0) { return(rc); } readbytes += rc; } return(readbytes); } int cnet_protsend(int sfd, const void *buf, int bytes) { int rc; char sizebuf[16]; bzero(sizebuf, 16); sprintf(sizebuf, "%d", bytes); rc = cnet_sendbuf(sfd, sizebuf, 16); if (rc < 0) { return(-1); } rc = cnet_sendbuf(sfd, buf, bytes); if (rc != bytes) { return(-1); } return(0); } int cnet_protrecv(int sfd, void **buf) { int rc, rsize; char sizebuf[16]; bzero(sizebuf, 16); rc = cnet_recvbuf(sfd, sizebuf, 16); if (rc != 16) { return(-1); } rsize = atoi(sizebuf); *buf = (char *)malloc(rsize+1); bzero(*buf, rsize+1); rc = cnet_recvbuf(sfd, *buf, rsize); if (rc != rsize) { return(-1); } return(0); }