Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <iostream>
00034
00035 #include "ana.hpp"
00036
00037 using namespace ana;
00038
00039 const port DEFAULT_PORT = "2000";
00040
00041 const char* const DEFAULT_ADDRESS = "127.0.0.1";
00042 const char* const DEFAULT_NAME = "Unnamed";
00043
00044
00045 void show_help(char* const command)
00046 {
00047 std::cout << "The following options should be given in order and are all optional:\n"
00048 "\tName: [recommended] Set name. Default=" << DEFAULT_NAME << std::endl <<
00049 "\tAddress: [optional] Set address. Default=" << DEFAULT_ADDRESS << std::endl <<
00050 "\tPort: [optional] Set port. Default=" << DEFAULT_PORT << std::endl <<
00051 "\tProxy address: [optional] Set proxy address." << std::endl <<
00052 "\tProxy port: [optional] Set proxy port." << std::endl <<
00053 "\tProxy user: [optional] Set proxy authentication user name." << std::endl <<
00054 "\tProxy password: [optional] Set proxy authentication password." << std::endl <<
00055 "Examples:\n" <<
00056 "\t" << command << " billy localhost 12345\n" <<
00057 "\t\tConnect to a local server on port 12345 with nick billy.\n" <<
00058 "\t" << command << " billy X.K.C.D 12345 localhost 3128 foo bar\n" <<
00059 "\t\tConnect to a remote server at X.K.C.D:12345 using a local proxy with credentials foo:bar.\n\n";
00060 ;
00061 }
00062
00063 struct connection_info
00064 {
00065 connection_info() :
00066 pt(DEFAULT_PORT),
00067 address(DEFAULT_ADDRESS),
00068 name(DEFAULT_NAME),
00069 proxyaddr(),
00070 proxyport(),
00071 user(),
00072 password()
00073 {
00074 }
00075
00076 bool use_proxy() const
00077 {
00078 return proxyaddr != "" && proxyport != "";
00079 }
00080
00081 port pt;
00082 std::string address;
00083 std::string name;
00084 std::string proxyaddr;
00085 std::string proxyport;
00086 std::string user;
00087 std::string password;
00088 };
00089
00090 class ChatClient : public ana::listener_handler,
00091 public ana::send_handler,
00092 public ana::connection_handler
00093 {
00094 public:
00095 ChatClient(connection_info ci) :
00096 conn_info_( ci ),
00097 continue_(true),
00098 client_( ana::client::create(ci.address, ci.pt) ),
00099 name_(ci.name)
00100 {
00101 }
00102
00103 std::string get_name(const std::string& msg)
00104 {
00105 size_t pos = msg.find(" ");
00106
00107 return msg.substr(pos+1);
00108 }
00109
00110 void parse_command(const std::string& msg)
00111 {
00112 if (msg[1] == 'n')
00113 {
00114 name_ = get_name(msg);
00115 }
00116 }
00117
00118 void run_input()
00119 {
00120 std::string msg;
00121 do
00122 {
00123 std::cout << name_ << " : ";
00124 std::getline(std::cin, msg);
00125
00126 if (msg[0] == '/')
00127 parse_command(msg);
00128
00129 if (msg == "/quit")
00130 std::cout << "\nExiting.\n";
00131 else
00132 if (!msg.empty())
00133 client_->send( ana::buffer( msg ), this);
00134
00135 } while ( (msg != "/quit") && continue_);
00136 }
00137
00138 void run()
00139 {
00140 try
00141 {
00142
00143 if ( ! conn_info_.use_proxy() )
00144 client_->connect( this );
00145 else
00146 client_->connect_through_proxy(conn_info_.proxyaddr,
00147 conn_info_.proxyport,
00148 this,
00149 conn_info_.user,
00150 conn_info_.password);
00151
00152 client_->set_listener_handler( this );
00153 client_->run();
00154
00155 std::cout << "Available commands: \n" <<
00156 " '/quit' : Quit. \n"
00157 " '/who' : List connected users. \n" <<
00158 " '/name name' : Change name." << std::endl;
00159
00160 run_input();
00161
00162 }
00163 catch(const std::exception& e)
00164 {
00165 std::cerr << e.what() << std::endl;
00166 }
00167
00168 delete client_;
00169 }
00170
00171 private:
00172
00173 virtual void handle_connect( ana::error_code error, net_id server_id )
00174 {
00175 if ( error )
00176 {
00177 std::cerr << "\nError connecting." << std::endl;
00178 continue_ = false;
00179 }
00180 else
00181 client_->send( ana::buffer( std::string("/name ") + name_) , this);
00182 }
00183
00184 virtual void handle_disconnect( ana::error_code error, net_id server_id)
00185 {
00186 std::cerr << "\nServer disconnected. Enter to exit." << std::endl;
00187 continue_ = false;
00188 }
00189
00190 virtual void handle_receive( ana::error_code error, net_id, ana::read_buffer msg)
00191 {
00192 if (! error)
00193 {
00194 std::cout << std::endl << msg->string()
00195 << std::endl << name_ << " : ";
00196 std::cout.flush();
00197 }
00198 }
00199
00200 virtual void handle_send( ana::error_code error, net_id client)
00201 {
00202 if ( error )
00203 std::cout << "Error. Timeout?" << std::endl;
00204 }
00205
00206 connection_info conn_info_;
00207 bool continue_;
00208 ana::client* client_;
00209 std::string name_;
00210 };
00211
00212 int main(int argc, char **argv)
00213 {
00214 show_help(argv[0]);
00215
00216 connection_info ci;
00217
00218 if ( argc > 1 )
00219 ci.name = argv[1];
00220 if ( argc > 2 )
00221 ci.address = argv[2];
00222 if ( argc > 3 )
00223 ci.pt = argv[3];
00224 if ( argc > 4 )
00225 ci.proxyaddr = argv[4];
00226 if ( argc > 5 )
00227 ci.proxyport = argv[5];
00228 if ( argc > 6 )
00229 ci.user = argv[6];
00230 if ( argc > 7 )
00231 ci.password = argv[7];
00232
00233 std::cout << "Main client app.: Starting client" << std::endl;
00234
00235 ChatClient client(ci);
00236 client.run();
00237 }