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 |