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