00001 #ifndef WIN32
00002 #include <cstdlib>
00003 #include <netdb.h>
00004 #else
00005 #include <winsock2.h>
00006 #include <ws2tcpip.h>
00007 #endif
00008 #include <fstream>
00009 #include <iostream>
00010 #include <cstring>
00011 #include <udt.h>
00012
00013 using namespace std;
00014
00015 #ifndef WIN32
00016 void* sendfile(void*);
00017 #else
00018 DWORD WINAPI sendfile(LPVOID);
00019 #endif
00020
00021 int main(int argc, char* argv[])
00022 {
00023
00024 if ((2 < argc) || ((2 == argc) && (0 == atoi(argv[1]))))
00025 {
00026 cout << "usage: sendfile [server_port]" << endl;
00027 return 0;
00028 }
00029
00030
00031 UDT::startup();
00032
00033 addrinfo hints;
00034 addrinfo* res;
00035
00036 memset(&hints, 0, sizeof(struct addrinfo));
00037 hints.ai_flags = AI_PASSIVE;
00038 hints.ai_family = AF_INET;
00039 hints.ai_socktype = SOCK_STREAM;
00040
00041 string service("9000");
00042 if (2 == argc)
00043 service = argv[1];
00044
00045 if (0 != getaddrinfo(NULL, service.c_str(), &hints, &res))
00046 {
00047 cout << "illegal port number or port is busy.\n" << endl;
00048 return 0;
00049 }
00050
00051 UDTSOCKET serv = UDT::socket(res->ai_family, res->ai_socktype, res->ai_protocol);
00052
00053
00054
00055 #ifdef WIN32
00056 int mss = 1052;
00057 UDT::setsockopt(serv, 0, UDT_MSS, &mss, sizeof(int));
00058 #endif
00059
00060 if (UDT::ERROR == UDT::bind(serv, res->ai_addr, res->ai_addrlen))
00061 {
00062 cout << "bind: " << UDT::getlasterror().getErrorMessage() << endl;
00063 return 0;
00064 }
00065
00066 freeaddrinfo(res);
00067
00068 cout << "server is ready at port: " << service << endl;
00069
00070 UDT::listen(serv, 10);
00071
00072 sockaddr_storage clientaddr;
00073 int addrlen = sizeof(clientaddr);
00074
00075 UDTSOCKET fhandle;
00076
00077 while (true)
00078 {
00079 if (UDT::INVALID_SOCK == (fhandle = UDT::accept(serv, (sockaddr*)&clientaddr, &addrlen)))
00080 {
00081 cout << "accept: " << UDT::getlasterror().getErrorMessage() << endl;
00082 return 0;
00083 }
00084
00085 char clienthost[NI_MAXHOST];
00086 char clientservice[NI_MAXSERV];
00087 getnameinfo((sockaddr *)&clientaddr, addrlen, clienthost, sizeof(clienthost), clientservice, sizeof(clientservice), NI_NUMERICHOST|NI_NUMERICSERV);
00088 cout << "new connection: " << clienthost << ":" << clientservice << endl;
00089
00090 #ifndef WIN32
00091 pthread_t filethread;
00092 pthread_create(&filethread, NULL, sendfile, new UDTSOCKET(fhandle));
00093 pthread_detach(filethread);
00094 #else
00095 CreateThread(NULL, 0, sendfile, new UDTSOCKET(fhandle), 0, NULL);
00096 #endif
00097 }
00098
00099 UDT::close(serv);
00100
00101
00102 UDT::cleanup();
00103
00104 return 0;
00105 }
00106
00107 #ifndef WIN32
00108 void* sendfile(void* usocket)
00109 #else
00110 DWORD WINAPI sendfile(LPVOID usocket)
00111 #endif
00112 {
00113 UDTSOCKET fhandle = *(UDTSOCKET*)usocket;
00114 delete (UDTSOCKET*)usocket;
00115
00116
00117 char file[1024];
00118 int len;
00119
00120 if (UDT::ERROR == UDT::recv(fhandle, (char*)&len, sizeof(int), 0))
00121 {
00122 cout << "recv: " << UDT::getlasterror().getErrorMessage() << endl;
00123 return 0;
00124 }
00125
00126 if (UDT::ERROR == UDT::recv(fhandle, file, len, 0))
00127 {
00128 cout << "recv: " << UDT::getlasterror().getErrorMessage() << endl;
00129 return 0;
00130 }
00131 file[len] = '\0';
00132
00133
00134 fstream ifs(file, ios::in | ios::binary);
00135
00136 ifs.seekg(0, ios::end);
00137 int64_t size = ifs.tellg();
00138 ifs.seekg(0, ios::beg);
00139
00140
00141 if (UDT::ERROR == UDT::send(fhandle, (char*)&size, sizeof(int64_t), 0))
00142 {
00143 cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;
00144 return 0;
00145 }
00146
00147 UDT::TRACEINFO trace;
00148 UDT::perfmon(fhandle, &trace);
00149
00150
00151 int64_t offset = 0;
00152 if (UDT::ERROR == UDT::sendfile(fhandle, ifs, offset, size))
00153 {
00154 cout << "sendfile: " << UDT::getlasterror().getErrorMessage() << endl;
00155 return 0;
00156 }
00157
00158 UDT::perfmon(fhandle, &trace);
00159 cout << "speed = " << trace.mbpsSendRate << "Mbits/sec" << endl;
00160
00161 UDT::close(fhandle);
00162
00163 ifs.close();
00164
00165 #ifndef WIN32
00166 return NULL;
00167 #else
00168 return 0;
00169 #endif
00170 }