| OLD | NEW |
| (Empty) |
| 1 #ifndef WIN32 | |
| 2 #include <cstdlib> | |
| 3 #include <netdb.h> | |
| 4 #else | |
| 5 #include <winsock2.h> | |
| 6 #include <ws2tcpip.h> | |
| 7 #endif | |
| 8 #include <fstream> | |
| 9 #include <iostream> | |
| 10 #include <cstring> | |
| 11 #include <udt.h> | |
| 12 | |
| 13 using namespace std; | |
| 14 | |
| 15 #ifndef WIN32 | |
| 16 void* sendfile(void*); | |
| 17 #else | |
| 18 DWORD WINAPI sendfile(LPVOID); | |
| 19 #endif | |
| 20 | |
| 21 int main(int argc, char* argv[]) | |
| 22 { | |
| 23 //usage: sendfile [server_port] | |
| 24 if ((2 < argc) || ((2 == argc) && (0 == atoi(argv[1])))) | |
| 25 { | |
| 26 cout << "usage: sendfile [server_port]" << endl; | |
| 27 return 0; | |
| 28 } | |
| 29 | |
| 30 // use this function to initialize the UDT library | |
| 31 UDT::startup(); | |
| 32 | |
| 33 addrinfo hints; | |
| 34 addrinfo* res; | |
| 35 | |
| 36 memset(&hints, 0, sizeof(struct addrinfo)); | |
| 37 hints.ai_flags = AI_PASSIVE; | |
| 38 hints.ai_family = AF_INET; | |
| 39 hints.ai_socktype = SOCK_STREAM; | |
| 40 | |
| 41 string service("9000"); | |
| 42 if (2 == argc) | |
| 43 service = argv[1]; | |
| 44 | |
| 45 if (0 != getaddrinfo(NULL, service.c_str(), &hints, &res)) | |
| 46 { | |
| 47 cout << "illegal port number or port is busy.\n" << endl; | |
| 48 return 0; | |
| 49 } | |
| 50 | |
| 51 UDTSOCKET serv = UDT::socket(res->ai_family, res->ai_socktype, res->ai_protoc
ol); | |
| 52 | |
| 53 // Windows UDP issue | |
| 54 // For better performance, modify HKLM\System\CurrentControlSet\Services\Afd\
Parameters\FastSendDatagramThreshold | |
| 55 #ifdef WIN32 | |
| 56 int mss = 1052; | |
| 57 UDT::setsockopt(serv, 0, UDT_MSS, &mss, sizeof(int)); | |
| 58 #endif | |
| 59 | |
| 60 if (UDT::ERROR == UDT::bind(serv, res->ai_addr, res->ai_addrlen)) | |
| 61 { | |
| 62 cout << "bind: " << UDT::getlasterror().getErrorMessage() << endl; | |
| 63 return 0; | |
| 64 } | |
| 65 | |
| 66 freeaddrinfo(res); | |
| 67 | |
| 68 cout << "server is ready at port: " << service << endl; | |
| 69 | |
| 70 UDT::listen(serv, 10); | |
| 71 | |
| 72 sockaddr_storage clientaddr; | |
| 73 int addrlen = sizeof(clientaddr); | |
| 74 | |
| 75 UDTSOCKET fhandle; | |
| 76 | |
| 77 while (true) | |
| 78 { | |
| 79 if (UDT::INVALID_SOCK == (fhandle = UDT::accept(serv, (sockaddr*)&clientad
dr, &addrlen))) | |
| 80 { | |
| 81 cout << "accept: " << UDT::getlasterror().getErrorMessage() << endl; | |
| 82 return 0; | |
| 83 } | |
| 84 | |
| 85 char clienthost[NI_MAXHOST]; | |
| 86 char clientservice[NI_MAXSERV]; | |
| 87 getnameinfo((sockaddr *)&clientaddr, addrlen, clienthost, sizeof(clienthos
t), clientservice, sizeof(clientservice), NI_NUMERICHOST|NI_NUMERICSERV); | |
| 88 cout << "new connection: " << clienthost << ":" << clientservice << endl; | |
| 89 | |
| 90 #ifndef WIN32 | |
| 91 pthread_t filethread; | |
| 92 pthread_create(&filethread, NULL, sendfile, new UDTSOCKET(fhandle)); | |
| 93 pthread_detach(filethread); | |
| 94 #else | |
| 95 CreateThread(NULL, 0, sendfile, new UDTSOCKET(fhandle), 0, NULL); | |
| 96 #endif | |
| 97 } | |
| 98 | |
| 99 UDT::close(serv); | |
| 100 | |
| 101 // use this function to release the UDT library | |
| 102 UDT::cleanup(); | |
| 103 | |
| 104 return 0; | |
| 105 } | |
| 106 | |
| 107 #ifndef WIN32 | |
| 108 void* sendfile(void* usocket) | |
| 109 #else | |
| 110 DWORD WINAPI sendfile(LPVOID usocket) | |
| 111 #endif | |
| 112 { | |
| 113 UDTSOCKET fhandle = *(UDTSOCKET*)usocket; | |
| 114 delete (UDTSOCKET*)usocket; | |
| 115 | |
| 116 // aquiring file name information from client | |
| 117 char file[1024]; | |
| 118 int len; | |
| 119 | |
| 120 if (UDT::ERROR == UDT::recv(fhandle, (char*)&len, sizeof(int), 0)) | |
| 121 { | |
| 122 cout << "recv: " << UDT::getlasterror().getErrorMessage() << endl; | |
| 123 return 0; | |
| 124 } | |
| 125 | |
| 126 if (UDT::ERROR == UDT::recv(fhandle, file, len, 0)) | |
| 127 { | |
| 128 cout << "recv: " << UDT::getlasterror().getErrorMessage() << endl; | |
| 129 return 0; | |
| 130 } | |
| 131 file[len] = '\0'; | |
| 132 | |
| 133 // open the file | |
| 134 fstream ifs(file, ios::in | ios::binary); | |
| 135 | |
| 136 ifs.seekg(0, ios::end); | |
| 137 int64_t size = ifs.tellg(); | |
| 138 ifs.seekg(0, ios::beg); | |
| 139 | |
| 140 // send file size information | |
| 141 if (UDT::ERROR == UDT::send(fhandle, (char*)&size, sizeof(int64_t), 0)) | |
| 142 { | |
| 143 cout << "send: " << UDT::getlasterror().getErrorMessage() << endl; | |
| 144 return 0; | |
| 145 } | |
| 146 | |
| 147 UDT::TRACEINFO trace; | |
| 148 UDT::perfmon(fhandle, &trace); | |
| 149 | |
| 150 // send the file | |
| 151 int64_t offset = 0; | |
| 152 if (UDT::ERROR == UDT::sendfile(fhandle, ifs, offset, size)) | |
| 153 { | |
| 154 cout << "sendfile: " << UDT::getlasterror().getErrorMessage() << endl; | |
| 155 return 0; | |
| 156 } | |
| 157 | |
| 158 UDT::perfmon(fhandle, &trace); | |
| 159 cout << "speed = " << trace.mbpsSendRate << "Mbits/sec" << endl; | |
| 160 | |
| 161 UDT::close(fhandle); | |
| 162 | |
| 163 ifs.close(); | |
| 164 | |
| 165 #ifndef WIN32 | |
| 166 return NULL; | |
| 167 #else | |
| 168 return 0; | |
| 169 #endif | |
| 170 } | |
| OLD | NEW |