IBR-DTNSuite
0.8
|
00001 /* 00002 * dtnrecv-ng.cpp 00003 * 00004 * Created on: 01.07.2011 00005 * Author: morgenro 00006 */ 00007 00008 #include "config.h" 00009 #include "ibrdtn/api/APIClient.h" 00010 #include "ibrdtn/api/FileBundle.h" 00011 #include "ibrcommon/net/tcpclient.h" 00012 00013 #include <csignal> 00014 #include <sys/types.h> 00015 #include <iostream> 00016 00017 void print_help() 00018 { 00019 cout << "-- dtnrecv-ng (IBR-DTN) --" << endl; 00020 cout << "Syntax: dtnrecv-ng [options]" << endl; 00021 cout << "* optional parameters *" << endl; 00022 cout << " -h|--help display this text" << endl; 00023 cout << " --file <filename> write the incoming data to the a file instead of the standard output" << endl; 00024 cout << " --name <name> set the application name (e.g. filetransfer)" << endl; 00025 // cout << " --timeout <seconds> receive timeout in seconds" << endl; 00026 cout << " --count <number> receive that many bundles" << endl; 00027 cout << " -U <socket> use UNIX domain sockets" << endl; 00028 } 00029 00030 dtn::api::APIClient *_client = NULL; 00031 ibrcommon::tcpclient *_conn = NULL; 00032 00033 int h = 0; 00034 bool _stdout = true; 00035 00036 void term(int signal) 00037 { 00038 if (!_stdout) 00039 { 00040 std::cout << h << " bundles received." << std::endl; 00041 } 00042 00043 if (signal >= 1) 00044 { 00045 if (_client != NULL) 00046 { 00047 _client->unblock_wait(); 00048 _conn->close(); 00049 } 00050 } 00051 } 00052 00053 int main(int argc, char *argv[]) 00054 { 00055 // catch process signals 00056 signal(SIGINT, term); 00057 signal(SIGTERM, term); 00058 00059 int ret = EXIT_SUCCESS; 00060 string filename = ""; 00061 string name = "filetransfer"; 00062 int timeout = 0; 00063 int count = 1; 00064 ibrcommon::File unixdomain; 00065 00066 for (int i = 0; i < argc; i++) 00067 { 00068 string arg = argv[i]; 00069 00070 // print help if requested 00071 if (arg == "-h" || arg == "--help") 00072 { 00073 print_help(); 00074 return ret; 00075 } 00076 00077 if (arg == "--name" && argc > i) 00078 { 00079 name = argv[i + 1]; 00080 } 00081 00082 if (arg == "--file" && argc > i) 00083 { 00084 filename = argv[i + 1]; 00085 _stdout = false; 00086 } 00087 00088 if (arg == "--timeout" && argc > i) 00089 { 00090 timeout = atoi(argv[i + 1]); 00091 } 00092 00093 if (arg == "--count" && argc > i) 00094 { 00095 count = atoi(argv[i + 1]); 00096 } 00097 00098 if (arg == "-U" && argc > i) 00099 { 00100 if (++i > argc) 00101 { 00102 std::cout << "argument missing!" << std::endl; 00103 return -1; 00104 } 00105 00106 unixdomain = ibrcommon::File(argv[i]); 00107 } 00108 } 00109 00110 try { 00111 // Create a stream to the server using TCP. 00112 ibrcommon::tcpclient conn; 00113 00114 // check if the unixdomain socket exists 00115 if (unixdomain.exists()) 00116 { 00117 // connect to the unix domain socket 00118 conn.open(unixdomain); 00119 } 00120 else 00121 { 00122 // connect to the standard local api port 00123 conn.open("127.0.0.1", 4550); 00124 00125 // enable nodelay option 00126 conn.enableNoDelay(); 00127 } 00128 00129 // Initiate a client for synchronous receiving 00130 dtn::api::APIClient client(conn); 00131 00132 // read the connection banner 00133 client.connect(); 00134 00135 // export objects for the signal handler 00136 _conn = &conn; 00137 _client = &client; 00138 00139 // register endpoint identifier 00140 client.setEndpoint(name); 00141 00142 std::fstream file; 00143 00144 if (!_stdout) 00145 { 00146 std::cout << "Wait for incoming bundle... " << std::endl; 00147 file.open(filename.c_str(), ios::in|ios::out|ios::binary|ios::trunc); 00148 file.exceptions(std::ios::badbit | std::ios::eofbit); 00149 } 00150 00151 h = 0; 00152 while ((h < count) && !conn.eof()) 00153 { 00154 // receive the next notify 00155 dtn::api::APIClient::Message n = client.wait(); 00156 00157 try { 00158 if (n.code == dtn::api::APIClient::API_STATUS_NOTIFY_BUNDLE) 00159 { 00160 dtn::api::Bundle b = client.get(); 00161 00162 // get the reference to the blob 00163 ibrcommon::BLOB::Reference ref = b.getData(); 00164 00165 // write the data to output 00166 if (_stdout) 00167 { 00168 cout << ref.iostream()->rdbuf(); 00169 } 00170 else 00171 { 00172 // write data to temporary file 00173 try { 00174 std::cout << "Bundle received (" << (h + 1) << ")." << endl; 00175 00176 file << ref.iostream()->rdbuf(); 00177 } catch (const ios_base::failure&) { 00178 00179 } 00180 } 00181 00182 // bundle received, increment counter 00183 h++; 00184 00185 // notify it as delivered 00186 client.notify_delivered(b); 00187 } 00188 } catch (const ibrcommon::Exception&) { 00189 // bundle get failed 00190 std::cerr << "bundle get failed" << std::endl; 00191 } 00192 } 00193 00194 if (!_stdout) 00195 { 00196 file.close(); 00197 std::cout << "done." << std::endl; 00198 } 00199 00200 // close the tcp connection 00201 conn.close(); 00202 } catch (const std::exception &ex) { 00203 std::cerr << "Error: " << ex.what() << std::endl; 00204 ret = EXIT_FAILURE; 00205 } 00206 00207 return ret; 00208 } 00209