Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdlib>
- #include <iostream>
- #include <boost/bind.hpp>
- #include <boost/smart_ptr.hpp>
- #include <boost/asio.hpp>
- #include <boost/thread.hpp>
- #include <boost/regex.hpp>
- #include <boost/lexical_cast.hpp>
- #include <string>
- using boost::asio::ip::tcp;
- const int max_length = 1000000;
- typedef boost::shared_ptr<tcp::socket> socket_ptr;
- unsigned short analyze_user_request(std::string& user_request, short unsigned* ID, std::string* request_value)
- {
- // function returns:
- // 0: if user request is incorrect
- // 1: if user requests "PUT" operation
- // 2: if user requests "GET" operation
- // Furthermore, if request is correct, its value (i.e. ID number and/or string) is saved to short unsigned and string values passed by pointers.
- boost::regex exp("^[[:space:]]*(PUT|GET)[[:space:]]+([[:digit:]]{1,2})(?:[[:space:]]+(.*))?$");
- boost::smatch what;
- if (regex_match(user_request, what, exp, boost::match_extra))
- {
- short unsigned id_number = boost::lexical_cast<short unsigned>(what[2]);
- if (what[1] == "PUT")
- {
- boost::regex exp1("^[a-zA-Z0-9]+$");
- std::string value = boost::lexical_cast<std::string>(what[3]);
- if (value.length() > 4095)
- return 0;
- if (!regex_match(value, exp1))
- return 0;
- else
- {
- *request_value = value;
- *ID = id_number;
- return 1;
- }
- }
- if (what[1] == "GET")
- {
- *ID = id_number;
- return 2;
- }
- }
- if (!regex_match(user_request, what, exp, boost::match_extra))
- return 0;
- }
- class Session
- {
- public:
- void handleRequest(socket_ptr sock)
- {
- try
- {
- for (;;)
- {
- char data[max_length];
- boost::system::error_code error;
- size_t length = sock->read_some(boost::asio::buffer(data), error);
- if (error == boost::asio::error::eof)
- break; // Connection closed cleanly by peer.
- else if (error)
- throw boost::system::system_error(error); // Some other error.
- // convert buffer data to string for further procession
- std::string line(boost::asio::buffers_begin(boost::asio::buffer(data)), boost::asio::buffers_begin(boost::asio::buffer(data)) + length);
- std::string reply; // will be "QK", "INVALID", or "OK <value>"
- unsigned short vID;
- unsigned short* ID = &vID;
- std::string vrequest_value;
- std::string* request_value = &vrequest_value;
- unsigned short output = analyze_user_request(line, ID, request_value);
- if (output == 1)
- {
- // PUT
- reply = "OK";
- user_array[*ID] = *request_value;
- }
- else if (output == 2)
- {
- // GET
- reply = user_array[*ID];
- if (reply == "")
- reply = "EMPTY";
- }
- else
- reply = "INVALID";
- boost::system::error_code ignored_error;
- size_t ans_len=reply.length();
- boost::asio::write(*sock, boost::asio::buffer(reply));
- }
- }
- catch (std::exception& e)
- {
- std::cerr << "Exception in thread: " << e.what() << "\n";
- }
- }
- private:
- std::string user_array[100];
- };
- typedef boost::shared_ptr<Session> SessionPtr;
- void server(boost::asio::io_service& io_service, short port)
- {
- tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
- for (;;)
- {
- socket_ptr sock(new tcp::socket(io_service));
- a.accept(*sock);
- SessionPtr newSession(new Session());
- boost::thread acceptThread(boost::bind(&Session::handleRequest, newSession, sock));
- }
- }
- int main(int argc, char* argv[])
- {
- try
- {
- if (argc != 2)
- {
- std::cerr << "Usage: blocking_tcp_echo_server <port>\n";
- return 1;
- }
- boost::asio::io_service io_service;
- using namespace std; // For atoi.
- server(io_service, atoi(argv[1]));
- }
- catch (std::exception& e)
- {
- std::cerr << "Exception: " << e.what() << "\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement