#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; string replace_string(string str, const string from, const string to) { size_t start_pos = str.find(from); if(start_pos == string::npos) return str; str.replace(start_pos, from.length(), to); return str; } void sigchld_handler(int s) { while(waitpid(-1, NULL, WNOHANG) > 0); } class Server { private: string PORT; int MAXDATASIZE; public: Server() { PORT = "3490"; MAXDATASIZE = 14096; } // get sockaddr, IPv4 or IPv6: void *get_in_addr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); } int start_server() { // first, load up address structs with getaddrinfo(): int socketfd, new_socketfd; struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; socklen_t their_addr_size, addr_size; struct sigaction sa; char s[INET6_ADDRSTRLEN]; int rv; int yes = 1; int BACKLOG = 10; int numbytes; unsigned char buf[MAXDATASIZE]; memset(&hints, 0, sizeof hints); // Make sure it is cleared hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever hints.ai_socktype = SOCK_STREAM; // TCP socket hints.ai_flags = AI_PASSIVE; // fill in my IP for me if ((rv = getaddrinfo(NULL, PORT.c_str(), &hints, &servinfo)) != 0) { cerr << "getaddrinfo: " << gai_strerror(rv) << endl; return -1; } // make a socket, bind it asap for(p = servinfo; p != NULL; p = p->ai_next) { if ((socketfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { //perror("server: socket"); cerr << "ERROR: Server: socket" << endl; continue; } if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { //perror("setsockopt"); cerr << "ERROR: setsockopt" << endl; exit(1); } if (bind(socketfd, p->ai_addr, p->ai_addrlen) == -1) { close(socketfd); //perror("server: bind"); cerr << "ERROR: server: bind" << endl; continue; } break; } //If the binding failed if ( p == NULL) { cerr << "Server: failed to bind" << endl; return -1; } //Free space, we do not need it anymore. freeaddrinfo(servinfo); //Listen to the socket (port) if ( listen(socketfd, BACKLOG) == -1) { cerr << "ERROR: listen" << endl; } // killing zombie processs (all dead processes) sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } cout << "Server: waiting for connections ...\n"<(buf), MAXDATASIZE); // Convert to unsigned char array to make it easier to handle buffer_str = replace_string(buffer_str, "Proxy-Connection: keep-alive","Connection: close"); // Make it connection Close instead of Keep-Alive buffer_str = replace_string(buffer_str, "Connection: keep-alive","Connection: close"); // Make it connection Close instead of Keep-Alive // removes host from GET, and saves it int first = buffer_str.find_first_of("/"); int last = buffer_str.find_first_of("/", first+2); int size_of_buf=buffer_str.size(); unsigned char host_request[MAXDATASIZE]; for (int a=0;a<=size_of_buf;a++) host_request[a]=buffer_str[a]; host_request[size_of_buf]='\0'; string host_name = ""; for(int i=first+2;iai_next) { if ((host_sockfd = socket(host_p->ai_family, host_p->ai_socktype, host_p->ai_protocol)) == -1) { perror("client: socket"); continue; } if (connect(host_sockfd, host_p->ai_addr, host_p->ai_addrlen) == -1) { close(host_sockfd); perror("client: connect"); continue; } break; } if (host_p == NULL) { fprintf(stderr, "client: failed to connect\n"); return 2; } inet_ntop(host_p->ai_family, get_in_addr((struct sockaddr *)host_p->ai_addr),s, sizeof s); //Converts the IP address from binary to IPv4/6-format //printf("client: connecting to %s\n", s); freeaddrinfo(host_servinfo); // all done with this structure /*Send the GET request to the server*/ send_message(host_sockfd, host_request, sizeof(host_request), "Webserver"); memset(&host_buf, 0, MAXDATASIZE); while (recv(host_sockfd, &host_buf, MAXDATASIZE, 0) > 0 ) { int len; len = sizeof(host_buf); if ( send_message(new_socketfd, (unsigned char *)host_buf, MAXDATASIZE, "Browser") == -1) { perror("sendall"); printf("We only sent %d bytes because of the error!\n", len); } memset(&host_buf, 0, MAXDATASIZE); } //close(host_sockfd); exit(0); } close(new_socketfd); } //cout << "server: got connection from " << s << endl; close(new_socketfd); // parent doesn't need this } return 1; } int send_message(int &socket,unsigned char msg[], int length, string too) { int total = 0; // how many bytes we've sent int bytesleft = length; // how many we have left to send int data_sent; while(total < length) { if ((data_sent = (send(socket, msg+total, bytesleft, 0))) == -1) { cerr << "ERROR: sending to " << too << endl; cerr << "We will lose a packet due to" << endl; perror("send"); cerr << "-------------------MEDDELANDE-------------------\n\n" << msg << endl << "--------------------------------------------------\n\n"; cerr << "Closing the connection\n"; return -1; } if (data_sent == -1) { break; } total += data_sent; bytesleft -= data_sent; } return total; } }; int main() { Server srv; srv.start_server(); }