#include #include #include #include #include #include #include #include #include #include #include #include #define POWER 1 #define ENGINE 2 #define FORWARD 4 #define TURN 8 #define LEFTRIGHT 16 #define LIGHTS 32 #define PROX 64 #define UNKNOWN 128 #define MAXDATASIZE 1024 //#define PONIEIP "192.168.1.20" #define PONIEIP "192.168.1.200" //#define PONIEIP "10.0.2.15" #define PONIEPORT 4500 #define SERVERPORT 4501 int pipes[2]; char sendbits; int sockfd; int newsockfd; char* substring(const char* str, size_t begin, size_t len) { if (str == 0 || strlen(str) == 0 || strlen(str) < begin || strlen(str) < (begin+len)) return 0; return strndup(str + begin, len); } void error(const char *msg) { perror(msg); exit(0); } const char *byte_to_binary (int x) { static char b[9]; b[0] = '\0'; int z; for (z = 128; z > 0; z >>= 1) { strcat(b, ((x & z) == z) ? "1" : "0"); } return b; } void setbit(int bittoset) { sendbits = sendbits | bittoset; } void unsetbit(int bittounset) { sendbits = sendbits & ~bittounset; } //int main(int argc, char *argv[]) int start_client(void) { int portno, n, nbytes; struct sockaddr_in serv_addr; struct hostent *server; bool send = false; char sendbuffer[1]; char recvbuffer[4]; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { error("ERROR opening socket"); } else { printf("Client says: Socket opened\n"); fflush(stdout); } server = gethostbyname(PONIEIP); if (server == NULL) { fprintf(stderr,"ERROR, no such host\n"); fflush(stdout); exit(0); } else { printf("Client says: Got host information\n"); fflush(stdout); } bzero((char *) &serv_addr, sizeof(serv_addr)); // Zero out the server address printf("Client says: Server info flushed\n"); fflush(stdout); serv_addr.sin_family = AF_INET; // set the connection type to TCP printf("Client says: Connection type - TCP\n"); fflush(stdout); bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); // copy the server address printf("Client says: Server info copied\n"); fflush(stdout); serv_addr.sin_port = htons(PONIEPORT); printf("Client says: Server port set (%i)\n", PONIEPORT); fflush(stdout); if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) { error("ERROR connecting"); } else { printf("Client says: Connection to PoNIE established\n"); fflush(stdout); } setbit(POWER); int x; for (x = 1; x < 1000; x++) { nbytes = read(pipes[0], recvbuffer, sizeof(recvbuffer)); if(nbytes == 4) { printf("< Client Received: \"%s\"\n",recvbuffer); fflush(stdout); //setbit(UNKNOWN); if(strcmp(recvbuffer, "FORW") == 0) { setbit(ENGINE + FORWARD); unsetbit(TURN); send = true; } if(strcmp(recvbuffer, "BAKW") == 0) { setbit(ENGINE); unsetbit(FORWARD + TURN); send = true; } if(strcmp(recvbuffer, "BAKL") == 0) { setbit(ENGINE + TURN + LEFTRIGHT); unsetbit(FORWARD); send = true; } if(strcmp(recvbuffer, "BAKR") == 0) { setbit(ENGINE + TURN); unsetbit(FORWARD + LEFTRIGHT); send = true; } if(strcmp(recvbuffer, "FORR") == 0) { setbit(FORWARD + ENGINE + TURN); unsetbit(LEFTRIGHT); send = true; } if(strcmp(recvbuffer, "FORL") == 0) { setbit(FORWARD + ENGINE + TURN + LEFTRIGHT); send = true; } if(strcmp(recvbuffer, "PROF") == 0) { unsetbit(POWER + FORWARD + ENGINE + TURN + LEFTRIGHT + PROX + LIGHTS); send = true; } if(strcmp(recvbuffer, "PRON") == 0) { setbit(POWER); send = true; } if(strcmp(recvbuffer, "STOP") == 0) { unsetbit(FORWARD + ENGINE + TURN + LEFTRIGHT); send = true; } if(strcmp(recvbuffer, "LGON") == 0) { setbit(LIGHTS); send = true; } if(strcmp(recvbuffer, "LGOF") == 0) { unsetbit(LIGHTS); send = true; } if(send == true) { printf("> Client Sending: %s\n", byte_to_binary(sendbits)); fflush(stdout); send = false; sendbuffer[0] = sendbits; n = write(sockfd,sendbuffer,1); if (n < 0) error("ERROR writing to socket"); } } sleep(1); bzero(recvbuffer,5); // Clear the buffer } n = read(sockfd,recvbuffer,16); if (n < 0) error("ERROR reading from socket"); return 0; } int start_server(void) { int newsockfd, portno, rc, result, i, n; char buffer[16], outbuffer[4]; socklen_t clilen; struct timeval timeout; fd_set fds; char * nl; struct sockaddr_in serv_addr, cli_addr; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = SERVERPORT; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sockfd,5); clilen = sizeof(cli_addr); while(1) { newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("ERROR on accept"); printf("Server says: Client connected\n"); fflush(stdout); while(fcntl(newsockfd, F_GETFL) != -1) { timeout.tv_sec = 3; timeout.tv_usec = 0; FD_ZERO(&fds); FD_SET(newsockfd, &fds); rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout); if (rc==-1) { printf("Server says: Pipe select error!\n"); fflush(stdout); return -1; } result = 0; // If a client sends data within three seconds (the timeout), do this if (rc > 0) { if (FD_ISSET(newsockfd, &fds)) { n = read(newsockfd,buffer,16); if (n < 0) error("ERROR reading from socket"); if (n == 0) { close(newsockfd); printf("Server says: Client disconnected\n"); fflush(stdout); continue; } strncpy(outbuffer, buffer, 4); printf("Server says: Received [%s]\n", outbuffer); fflush(stdout); write(pipes[1], outbuffer, (strlen(outbuffer) + 1)); // If we receive the shutdown signal, exit the loop function if(strcmp(substring(buffer, 0, 4), "SHDN") == 0) { return 0; } } // If the client doesn't send data within three seconds, do this. } else { } } } close(sockfd); return 0; } void shutdown( void ) { printf("Cleaning up\n"); fflush(stdout); close(sockfd); close(newsockfd); printf("Shutting down\n"); fflush(stdout); } void consoleout(char* output) { printf("%s\n", output); fflush(stdout); } int main(int argc, char** argv) { int childpid; if(pipe2(pipes, O_NONBLOCK) < 0) { perror("Pipe allocation failed"); exit(0); } switch(childpid=fork()){ case -1: perror("Problem with fork\n"); break; case 0: //Child start_server(); shutdown(); break; default: //Parent start_client(); waitpid(childpid,0,0); break; } }