├── .gitignore
├── allmake.sh
├── bench_mark.md
├── bench_mark
├── kcp_500.log
├── udt_50.log
└── udt_500.log
├── clean.sh
├── client
├── Makefile
├── main.cpp
├── test_util.cpp
├── test_util.h
├── threadsafe_queue.hpp
├── udt_client.cpp
└── udt_client.h
├── client_epoll
├── Makefile
├── main.cpp
├── test_util.cpp
├── test_util.h
├── threadsafe_queue.hpp
├── udt_client.cpp
└── udt_client.h
├── launcher_clients.sh
├── launcher_clients2.sh
├── launcher_clients3.sh
├── launcher_clients4.sh
├── readme.txt
├── server
├── Makefile
└── main.cpp
├── server_udt
├── Makefile
├── send_msg_buf.cpp
├── send_msg_buf.h
├── send_msg_ctrl.cpp
├── send_msg_ctrl.h
├── test_util.cpp
├── test_util.h
├── udt_epoll_def.h
├── udt_server.cpp
└── udt_server.h
├── udt4
├── LICENSE.txt
├── Makefile
├── README.txt
├── RELEASE_NOTES.txt
├── app
│ ├── Makefile
│ ├── appclient.cpp
│ ├── appserver.cpp
│ ├── cc.h
│ ├── recvfile.cpp
│ ├── sendfile.cpp
│ ├── test.cpp
│ ├── udcat_client.cpp
│ ├── udcat_common.cpp
│ ├── udcat_common.h
│ └── udcat_server.cpp
├── doc
│ ├── doc
│ │ ├── accept.htm
│ │ ├── bind.htm
│ │ ├── ccc.htm
│ │ ├── cleanup.htm
│ │ ├── close.htm
│ │ ├── connect.htm
│ │ ├── copy.htm
│ │ ├── ecode.htm
│ │ ├── epoll.htm
│ │ ├── error.htm
│ │ ├── footer.htm
│ │ ├── function.htm
│ │ ├── header.htm
│ │ ├── intro.htm
│ │ ├── listen.htm
│ │ ├── make.htm
│ │ ├── opt.htm
│ │ ├── peername.htm
│ │ ├── recv.htm
│ │ ├── recvfile.htm
│ │ ├── recvmsg.htm
│ │ ├── reference.htm
│ │ ├── select.htm
│ │ ├── selectex.htm
│ │ ├── send.htm
│ │ ├── sendfile.htm
│ │ ├── sendmsg.htm
│ │ ├── socket.htm
│ │ ├── sockname.htm
│ │ ├── startup.htm
│ │ ├── structure.htm
│ │ ├── t-cc.htm
│ │ ├── t-config.htm
│ │ ├── t-data.htm
│ │ ├── t-error.htm
│ │ ├── t-file.htm
│ │ ├── t-firewall.htm
│ │ ├── t-hello.htm
│ │ ├── t-intro.htm
│ │ ├── t-msg.htm
│ │ ├── t-udt3.htm
│ │ ├── trace.htm
│ │ ├── treeview.css
│ │ ├── tutorial.htm
│ │ └── udtdoc.css
│ ├── hlp
│ │ ├── ix_book.gif
│ │ ├── ix_down.gif
│ │ ├── ix_end.gif
│ │ ├── ix_endm.gif
│ │ ├── ix_endp.gif
│ │ ├── ix_leaf.gif
│ │ ├── ix_line.gif
│ │ ├── ix_link.gif
│ │ ├── ix_list.gif
│ │ ├── ix_listm.gif
│ │ ├── ix_listp.gif
│ │ ├── ix_open.gif
│ │ ├── ix_space.gif
│ │ └── ix_up.gif
│ ├── index.htm
│ └── main.htm
├── src
│ ├── Makefile
│ ├── api.cpp
│ ├── api.h
│ ├── buffer.cpp
│ ├── buffer.h
│ ├── cache.cpp
│ ├── cache.h
│ ├── ccc.cpp
│ ├── ccc.h
│ ├── channel.cpp
│ ├── channel.h
│ ├── common.cpp
│ ├── common.h
│ ├── core.cpp
│ ├── core.h
│ ├── epoll.cpp
│ ├── epoll.h
│ ├── list.cpp
│ ├── list.h
│ ├── md5.cpp
│ ├── md5.h
│ ├── packet.cpp
│ ├── packet.h
│ ├── queue.cpp
│ ├── queue.h
│ ├── udt.h
│ ├── window.cpp
│ └── window.h
├── ssl
│ ├── Makefile
│ ├── e_os.h
│ ├── epoll.cpp
│ ├── server.pem
│ ├── tls_client.cpp
│ ├── tls_common.cpp
│ ├── tls_common.h
│ └── tls_server.cpp
├── tuner
│ ├── Makefile
│ ├── README.md
│ ├── appclient.cpp
│ ├── appserver.cpp
│ ├── cc.h
│ ├── recvfile.cpp
│ ├── sendfile.cpp
│ ├── settings.txt
│ └── tune.sh
└── win
│ ├── appclient.vcproj
│ ├── appserver.vcproj
│ ├── recvfile.vcproj
│ ├── sendfile.vcproj
│ ├── test.vcproj
│ ├── udt.sln
│ └── udt.vcproj
└── utest_server
├── Makefile
├── SendMsgBufTest.cpp
├── SendMsgBufTest.h
├── main.cpp
├── test_def.h
├── test_util.cpp
├── test_util.h
├── test_util_test.cpp
└── test_util_test.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 |
19 | # Compiled Static libraries
20 | *.lai
21 | *.la
22 | *.a
23 | *.lib
24 |
25 | # Executables
26 | *.exe
27 | *.out
28 | *.app
29 |
30 | tags
31 | client/client
32 | client_epoll/client_epoll
33 | server_udt/server_udt.a
34 | server/server
35 | utest_server/utest_server
36 |
37 | install_pack
38 | cppunit-1.12.1
39 | error.log
40 | error2.log
41 |
42 | udt4/app/appclient
43 | udt4/app/appserver
44 | udt4/app/recvfile
45 | udt4/app/sendfile
46 | udt4/app/test
47 | udt4/app/udcat_client
48 | udt4/app/udcat_server
49 | udt4/src/udt
50 |
--------------------------------------------------------------------------------
/allmake.sh:
--------------------------------------------------------------------------------
1 | OLD_PWD="$( pwd )"
2 |
3 | OS="LINUX"
4 | #OS="OSX"
5 |
6 | ARCH="IA32"
7 |
8 | echo "" && echo "" && echo "[-------------------------------]" && echo " udt4" && echo "[-------------------------------]" && \
9 | cd ./udt4/ && make -e os=$OS arch=$ARCH && \
10 | echo "" && echo "" && echo "[-------------------------------]" && echo " server_udt" && echo "[-------------------------------]" && \
11 | cd ../server_udt/ && make -e os=$OS arch=$ARCH && \
12 | echo "" && echo "" && echo "[-------------------------------]" && echo " server" && echo "[-------------------------------]" && \
13 | cd ../server/ && make -e os=$OS arch=$ARCH && \
14 | echo "" && echo "" && echo "[-------------------------------]" && echo " client_epoll" && echo "[-------------------------------]" && \
15 | cd ../client_epoll/ && make -e os=$OS arch=$ARCH && \
16 | echo "" && echo "" && echo "[-------------------------------]" && echo " client" && echo "[-------------------------------]" && \
17 | cd ../client/ && make -e os=$OS arch=$ARCH && \
18 | echo "" && echo "" && echo "[-------------------------------]" && echo " utest_server" && echo "[-------------------------------]" && \
19 | cd ../utest_server/ && make -e os=$OS arch=$ARCH && \
20 | echo ""
21 |
22 | # restore old path.
23 | cd $OLD_PWD
24 |
--------------------------------------------------------------------------------
/bench_mark.md:
--------------------------------------------------------------------------------
1 | Bench mark of the client_epoll with server_epoll.
2 | This bench mark is for realtime pvp game. For example, the multiplayer first person shooting game.
3 | The requirement of realtime pvp game is packet is small and frequently. It wants a minimal delay. And the worst delay is not so worst.
4 |
5 | The tests run server on a server on internet. The Bandwidth of internet is 5M.
6 | And run client_epoll or client on home computer var wifi. The Bandwidth of ADSL is 10M.
7 | Both Bandwidth is much bigger than we need (10 times more). And I use iptraf to verify it.
8 |
9 | The client send 500 bytes data as one packet in every 50 milliseconds. Or 50 bytes for another test.
10 | The server sendback the data after receiving the packet.
11 |
12 | server is a udt epoll server.
13 | ./server/server 0.0.0.0 23456 >/dev/null
14 |
15 | client_epoll is a client using udt epoll.
16 | ./client_epoll/client_epoll 20003 120.26.200.xxx 23456 500 2>>./error.log
17 |
18 | client is a client using udt unblock socket by checking read/write frequently.
19 | ./client/client 20003 120.26.200.xxx 23456 500 2>>./error.log
20 |
21 |
22 | The conclusion of this bench mark test:
23 | The udt epoll is not good at realtime pvp game.
24 | The latency is perfect at normal.
25 | But the udt will fall into a badly situation if there is a small lag.
26 |
27 |
28 | 1. [Bench mark log for 500 bytes in every 50 milliseconds](https://github.com/libinzhangyuan/udt_patch_for_epoll/blob/master/bench_mark/udt_500.log).
29 | 2. [Bench mark log for 50 bytes in every 50 milliseconds](https://github.com/libinzhangyuan/udt_patch_for_epoll/blob/master/bench_mark/udt_50.log).
30 | 3. [Bench mark log for 500 bytes in every 50 milliseconds using another framework kcp](https://github.com/libinzhangyuan/udt_patch_for_epoll/blob/master/bench_mark/kcp_500.log). https://github.com/libinzhangyuan/asio_kcp
31 | I run 2 and 3 at the same time. So you can verify the network.
32 |
33 | The test log of client is some like client_epoll. I ignore the log from client.
34 |
--------------------------------------------------------------------------------
/clean.sh:
--------------------------------------------------------------------------------
1 | OLD_PWD="$( pwd )"
2 |
3 | cd ./server_udt/ && make clean && \
4 | cd ../utest_server/ && make clean && \
5 | cd ../server/ && make clean && \
6 | cd ../client_epoll/ && make clean && \
7 | cd ../client/ && make clean && \
8 | echo ""
9 |
10 | # restore old path.
11 | cd $OLD_PWD
12 |
--------------------------------------------------------------------------------
/client/test_util.cpp:
--------------------------------------------------------------------------------
1 | #include "test_util.h"
2 | #include
3 |
4 | std::string test_str(const std::string& str_prefix, const size_t str_len)
5 | {
6 | std::ostringstream ostr;
7 | ostr << str_prefix << ':';
8 | std::string str = ostr.str();
9 |
10 | // when len <= prefixLen
11 | // test_str(adfadf, 3) == adf
12 | if (str.size() >= str_len)
13 | {
14 | str.resize(str_len);
15 | return str;
16 | }
17 |
18 | // when len < 20
19 | // test_str(adf, 13) == adfa:67890123
20 | if (str_len < 20)
21 | {
22 | for (size_t i = str.size() + 1; i <= str_len; ++i)
23 | str.push_back(char(((i % 10) + 0x30)));
24 | return str;
25 | }
26 |
27 | // when len >= 20
28 | // test_str(asdf, 45) = asdf:=====(20_56789)(30_56789)12345
29 | {
30 | // asdf:=====
31 | str.resize(10, '=');
32 |
33 | // (20_56789)(30_56789)
34 | while (str.size() + 10 <= str_len)
35 | {
36 | const size_t new_len = str.size() + 10;
37 | std::ostringstream tmp_ostrm;
38 | tmp_ostrm << str << "(" << new_len << '_';
39 | str = tmp_ostrm.str();
40 | for (size_t i = str.size() + 1; i < new_len; ++i)
41 | str.push_back(char(((i % 10) + 0x30)));
42 | str += ')';
43 | }
44 |
45 | // 12345
46 | if (str.size() < str_len)
47 | {
48 | for (size_t i = str.size() + 1; i <= str_len; ++i)
49 | {
50 | char c = ((i % 10) + 0x30);
51 | str.push_back(c);
52 | }
53 | }
54 | return str;
55 | }
56 |
57 | return str;
58 | }
59 |
--------------------------------------------------------------------------------
/client/test_util.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _DD_TEST_UTIL_H__
3 | #define _DD_TEST_UTIL_H__
4 | #include
5 |
6 | #include
7 |
8 | // when len <= prefixLen
9 | // test_str(adfadf, 3) == adf
10 | // when len < 20
11 | // test_str(adf, 13) == adfa:67890123
12 | // when len >= 20
13 | // test_str(asdf, 45) = asdf:=====(20_56789)(30_56789)12345
14 | std::string test_str(const std::string& str_prefix, const size_t str_len);
15 |
16 | /* get system time */
17 | static inline void itimeofday(long *sec, long *usec)
18 | {
19 | struct timeval time;
20 | gettimeofday(&time, NULL);
21 | if (sec) *sec = time.tv_sec;
22 | if (usec) *usec = time.tv_usec;
23 | }
24 |
25 | /* get clock in millisecond 64 */
26 | static inline uint64_t iclock64(void)
27 | {
28 | long s, u;
29 | uint64_t value;
30 | itimeofday(&s, &u);
31 | value = ((uint64_t)s) * 1000 + (u / 1000);
32 | return value;
33 | }
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/client/threadsafe_queue.hpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | template
7 | class threadsafe_queue
8 | {
9 | private:
10 | mutable std::mutex mut;
11 | std::queue data_queue;
12 | std::condition_variable data_cond;
13 | public:
14 | threadsafe_queue(){}
15 | threadsafe_queue(threadsafe_queue const& other)
16 | {
17 | std::lock_guard lk(other.mut);
18 | data_queue=other.data_queue;
19 | }
20 | size_t size()
21 | {
22 | std::lock_guard lk(mut);
23 | return data_queue.size();
24 | }
25 | void push(T new_value)
26 | {
27 | std::lock_guard lk(mut);
28 | data_queue.push(new_value);
29 | data_cond.notify_one();
30 | }
31 | void wait_and_pop(T& value)
32 | {
33 | std::unique_lock lk(mut);
34 | data_cond.wait(lk,[this]{return !data_queue.empty();});
35 | value=data_queue.front();
36 | data_queue.pop();
37 | }
38 | std::shared_ptr wait_and_pop()
39 | {
40 | std::unique_lock lk(mut);
41 | data_cond.wait(lk,[this]{return !data_queue.empty();});
42 | std::shared_ptr res(std::make_shared(data_queue.front()));
43 | data_queue.pop();
44 | return res;
45 | }
46 | bool try_pop(T& value)
47 | {
48 | std::lock_guard lk(mut);
49 | if(data_queue.empty())
50 | return false;
51 | value=data_queue.front();
52 | data_queue.pop();
53 | return true;
54 | }
55 | std::shared_ptr try_pop()
56 | {
57 | std::lock_guard lk(mut);
58 | if(data_queue.empty())
59 | return std::shared_ptr();
60 | std::shared_ptr res(std::make_shared(data_queue.front()));
61 | data_queue.pop();
62 | return res;
63 | }
64 | std::queue&& grab_all2(void)
65 | {
66 | std::queue ret;
67 |
68 | {
69 | std::lock_guard lk(mut);
70 | std::swap(ret, data_queue);
71 | }
72 |
73 | return std::move(ret);
74 | }
75 | std::queue grab_all(void)
76 | {
77 | std::queue ret;
78 |
79 | {
80 | std::lock_guard lk(mut);
81 | std::swap(ret, data_queue);
82 | }
83 |
84 | return ret;
85 | }
86 | bool empty() const
87 | {
88 | std::lock_guard lk(mut);
89 | return data_queue.empty();
90 | }
91 | };
92 |
--------------------------------------------------------------------------------
/client/udt_client.h:
--------------------------------------------------------------------------------
1 | #ifndef __UDT_CLIENT_H_
2 | #define __UDT_CLIENT_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include "threadsafe_queue.hpp"
12 |
13 |
14 | typedef int UDTSOCKET;
15 | typedef std::function&)> recv_callback_func_t;
16 | typedef std::shared_ptr msg_ptr_t;
17 |
18 | // the UDTClient will create another thread for UDT sending and recving.
19 | class UDTClient : public std::enable_shared_from_this
20 | {
21 | public:
22 | // when recv_func valid,
23 | // recv_callback_func will be called by another thread when a package recved. recv_callback_func should be thread safe.
24 | // when recv_func invalid,
25 | // packages recved will stored in queue. You should call TryRecvMsg frequently (10 milliseconds for example) to get the recved msg.
26 | UDTClient(int local_port, const std::string& ip_connect_to, int port_connect_to, recv_callback_func_t recv_func = nullptr);
27 | int Start(void);
28 |
29 | void SendMsg(msg_ptr_t msg);
30 | size_t SendMsgQueueSize(void);
31 | std::deque RecvMsg(void); // todo: using move symatic
32 |
33 | private:
34 | void TryGrabMsg(void);
35 |
36 | void TrySendMsg(void);
37 |
38 | // return 0 means send buf full. Need send at next loop.
39 | // return 1 means send ok. Can send other package.
40 | // return -1 means badly error. Need stop.
41 | int DoSendOneMsg(const std::string& msg);
42 |
43 | void TryRecvMsg(void);
44 | void DoRecvMsg(bool& bHaveMsgStill);
45 | int Run(void);
46 | int CreateSocket(void);
47 | int Connect(void);
48 |
49 | private:
50 | recv_callback_func_t recv_callback_func_;
51 | threadsafe_queue< msg_ptr_t > send_msg_queue_;
52 | std::queue send_msg_buff_;
53 |
54 | int local_port_;
55 | std::string ip_connect_to_;
56 | int port_connect_to_;
57 |
58 | std::thread udt_thread_;
59 | UDTSOCKET sock_;
60 | char udtbuf_[1024 * 100];
61 | size_t udtbuf_recved_len_;
62 | int udt_running_;
63 | int udt_eid_;
64 | };
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/client_epoll/test_util.cpp:
--------------------------------------------------------------------------------
1 | #include "test_util.h"
2 | #include
3 |
4 | std::string test_str(const std::string& str_prefix, const size_t str_len)
5 | {
6 | std::ostringstream ostr;
7 | ostr << str_prefix << ':';
8 | std::string str = ostr.str();
9 |
10 | // when len <= prefixLen
11 | // test_str(adfadf, 3) == adf
12 | if (str.size() >= str_len)
13 | {
14 | str.resize(str_len);
15 | return str;
16 | }
17 |
18 | // when len < 20
19 | // test_str(adf, 13) == adfa:67890123
20 | if (str_len < 20)
21 | {
22 | for (size_t i = str.size() + 1; i <= str_len; ++i)
23 | str.push_back(char(((i % 10) + 0x30)));
24 | return str;
25 | }
26 |
27 | // when len >= 20
28 | // test_str(asdf, 45) = asdf:=====(20_56789)(30_56789)12345
29 | {
30 | // asdf:=====
31 | str.resize(10, '=');
32 |
33 | // (20_56789)(30_56789)
34 | while (str.size() + 10 <= str_len)
35 | {
36 | const size_t new_len = str.size() + 10;
37 | std::ostringstream tmp_ostrm;
38 | tmp_ostrm << str << "(" << new_len << '_';
39 | str = tmp_ostrm.str();
40 | for (size_t i = str.size() + 1; i < new_len; ++i)
41 | str.push_back(char(((i % 10) + 0x30)));
42 | str += ')';
43 | }
44 |
45 | // 12345
46 | if (str.size() < str_len)
47 | {
48 | for (size_t i = str.size() + 1; i <= str_len; ++i)
49 | {
50 | char c = ((i % 10) + 0x30);
51 | str.push_back(c);
52 | }
53 | }
54 | return str;
55 | }
56 |
57 | return str;
58 | }
59 |
--------------------------------------------------------------------------------
/client_epoll/test_util.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _DD_TEST_UTIL_H__
3 | #define _DD_TEST_UTIL_H__
4 | #include
5 |
6 | #include
7 |
8 | // when len <= prefixLen
9 | // test_str(adfadf, 3) == adf
10 | // when len < 20
11 | // test_str(adf, 13) == adfa:67890123
12 | // when len >= 20
13 | // test_str(asdf, 45) = asdf:=====(20_56789)(30_56789)12345
14 | std::string test_str(const std::string& str_prefix, const size_t str_len);
15 |
16 | /* get system time */
17 | static inline void itimeofday(long *sec, long *usec)
18 | {
19 | struct timeval time;
20 | gettimeofday(&time, NULL);
21 | if (sec) *sec = time.tv_sec;
22 | if (usec) *usec = time.tv_usec;
23 | }
24 |
25 | /* get clock in millisecond 64 */
26 | static inline uint64_t iclock64(void)
27 | {
28 | long s, u;
29 | uint64_t value;
30 | itimeofday(&s, &u);
31 | value = ((uint64_t)s) * 1000 + (u / 1000);
32 | return value;
33 | }
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/client_epoll/threadsafe_queue.hpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | template
7 | class threadsafe_queue
8 | {
9 | private:
10 | mutable std::mutex mut;
11 | std::queue data_queue;
12 | std::condition_variable data_cond;
13 | public:
14 | threadsafe_queue(){}
15 | threadsafe_queue(threadsafe_queue const& other)
16 | {
17 | std::lock_guard lk(other.mut);
18 | data_queue=other.data_queue;
19 | }
20 | size_t size()
21 | {
22 | std::lock_guard lk(mut);
23 | return data_queue.size();
24 | }
25 | void push(T new_value)
26 | {
27 | std::lock_guard lk(mut);
28 | data_queue.push(new_value);
29 | data_cond.notify_one();
30 | }
31 | void wait_and_pop(T& value)
32 | {
33 | std::unique_lock lk(mut);
34 | data_cond.wait(lk,[this]{return !data_queue.empty();});
35 | value=data_queue.front();
36 | data_queue.pop();
37 | }
38 | std::shared_ptr wait_and_pop()
39 | {
40 | std::unique_lock lk(mut);
41 | data_cond.wait(lk,[this]{return !data_queue.empty();});
42 | std::shared_ptr res(std::make_shared(data_queue.front()));
43 | data_queue.pop();
44 | return res;
45 | }
46 | bool try_pop(T& value)
47 | {
48 | std::lock_guard lk(mut);
49 | if(data_queue.empty())
50 | return false;
51 | value=data_queue.front();
52 | data_queue.pop();
53 | return true;
54 | }
55 | std::shared_ptr try_pop()
56 | {
57 | std::lock_guard lk(mut);
58 | if(data_queue.empty())
59 | return std::shared_ptr();
60 | std::shared_ptr res(std::make_shared(data_queue.front()));
61 | data_queue.pop();
62 | return res;
63 | }
64 | std::queue&& grab_all2(void)
65 | {
66 | std::queue ret;
67 |
68 | {
69 | std::lock_guard lk(mut);
70 | std::swap(ret, data_queue);
71 | }
72 |
73 | return std::move(ret);
74 | }
75 | std::queue grab_all(void)
76 | {
77 | std::queue ret;
78 |
79 | {
80 | std::lock_guard lk(mut);
81 | std::swap(ret, data_queue);
82 | }
83 |
84 | return ret;
85 | }
86 | bool empty() const
87 | {
88 | std::lock_guard lk(mut);
89 | return data_queue.empty();
90 | }
91 | };
92 |
--------------------------------------------------------------------------------
/client_epoll/udt_client.h:
--------------------------------------------------------------------------------
1 | #ifndef __UDT_CLIENT_H_
2 | #define __UDT_CLIENT_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include "threadsafe_queue.hpp"
12 |
13 |
14 | typedef int UDTSOCKET;
15 | typedef std::function&)> recv_callback_func_t;
16 | typedef std::shared_ptr msg_ptr_t;
17 |
18 | // the UDTClient will create another thread for UDT sending and recving.
19 | class UDTClient : public std::enable_shared_from_this
20 | {
21 | public:
22 | // when recv_func valid,
23 | // recv_callback_func will be called by another thread when a package recved. recv_callback_func should be thread safe.
24 | // when recv_func invalid,
25 | // packages recved will stored in queue. You should call TryRecvMsg frequently (10 milliseconds for example) to get the recved msg.
26 | UDTClient(int local_port, const std::string& ip_connect_to, int port_connect_to, recv_callback_func_t recv_func = nullptr);
27 | int Start(void);
28 |
29 | void SendMsg(msg_ptr_t msg);
30 | size_t SendMsgQueueSize(void);
31 | std::deque RecvMsg(void); // todo: using move symatic
32 |
33 | private:
34 | void TryGrabMsg(void);
35 |
36 | void TrySendMsg(const std::set& writefds);
37 |
38 | // return 0 means send buf full. Need send at next epoll return.
39 | // return 1 means send ok. Can send other package.
40 | // return -1 means badly error. Need stop.
41 | int DoSendOneMsg(const std::string& msg);
42 |
43 | void TryRecvMsg(const std::set& readfds);
44 | void DoRecvMsg(const UDTSOCKET& sock, bool& bHaveMsgStill);
45 | int Run(void);
46 | int CreateSocket(void);
47 | int Connect(void);
48 |
49 | private:
50 | recv_callback_func_t recv_callback_func_;
51 | threadsafe_queue< msg_ptr_t > send_msg_queue_;
52 | std::queue send_msg_buff_;
53 |
54 | int local_port_;
55 | std::string ip_connect_to_;
56 | int port_connect_to_;
57 |
58 | std::thread udt_thread_;
59 | UDTSOCKET sock_;
60 | char udtbuf_[1024 * 100];
61 | size_t udtbuf_recved_len_;
62 | int udt_running_;
63 | int udt_eid_;
64 | };
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/launcher_clients.sh:
--------------------------------------------------------------------------------
1 | # 1 - 60
2 | ./client_udt/client_udt 22220 120.26.200.117 23456 1400 >/dev/null &
3 | ./client_udt/client_udt 22221 120.26.200.117 23456 1400 >/dev/null &
4 | ./client_udt/client_udt 22222 120.26.200.117 23456 1400 >/dev/null &
5 | ./client_udt/client_udt 22223 120.26.200.117 23456 1400 >/dev/null &
6 | ./client_udt/client_udt 22224 120.26.200.117 23456 1400 >/dev/null &
7 | ./client_udt/client_udt 22225 120.26.200.117 23456 1400 >/dev/null &
8 | ./client_udt/client_udt 22226 120.26.200.117 23456 1400 >/dev/null &
9 | ./client_udt/client_udt 22227 120.26.200.117 23456 1400 >/dev/null &
10 | ./client_udt/client_udt 22228 120.26.200.117 23456 1400 >/dev/null &
11 | ./client_udt/client_udt 22229 120.26.200.117 23456 1400 >/dev/null &
12 | ./client_udt/client_udt 22230 120.26.200.117 23456 1400 >/dev/null &
13 | ./client_udt/client_udt 22231 120.26.200.117 23456 1400 >/dev/null &
14 | ./client_udt/client_udt 22232 120.26.200.117 23456 1400 >/dev/null &
15 | ./client_udt/client_udt 22233 120.26.200.117 23456 1400 >/dev/null &
16 | ./client_udt/client_udt 22234 120.26.200.117 23456 1400 >/dev/null &
17 | ./client_udt/client_udt 22235 120.26.200.117 23456 1400 >/dev/null &
18 | ./client_udt/client_udt 22236 120.26.200.117 23456 1400 >/dev/null &
19 | ./client_udt/client_udt 22237 120.26.200.117 23456 1400 >/dev/null &
20 | ./client_udt/client_udt 22238 120.26.200.117 23456 1400 >/dev/null &
21 | ./client_udt/client_udt 22239 120.26.200.117 23456 1400 >/dev/null &
22 |
23 | ./client_udt/client_udt 22240 120.26.200.117 23456 1400 >/dev/null &
24 | ./client_udt/client_udt 22241 120.26.200.117 23456 1400 >/dev/null &
25 | ./client_udt/client_udt 22242 120.26.200.117 23456 1400 >/dev/null &
26 | ./client_udt/client_udt 22243 120.26.200.117 23456 1400 >/dev/null &
27 | ./client_udt/client_udt 22244 120.26.200.117 23456 1400 >/dev/null &
28 | ./client_udt/client_udt 22245 120.26.200.117 23456 1400 >/dev/null &
29 | ./client_udt/client_udt 22246 120.26.200.117 23456 1400 >/dev/null &
30 | ./client_udt/client_udt 22247 120.26.200.117 23456 1400 >/dev/null &
31 | ./client_udt/client_udt 22248 120.26.200.117 23456 1400 >/dev/null &
32 | ./client_udt/client_udt 22249 120.26.200.117 23456 1400 >/dev/null &
33 | ./client_udt/client_udt 22250 120.26.200.117 23456 1400 >/dev/null &
34 | ./client_udt/client_udt 22251 120.26.200.117 23456 1400 >/dev/null &
35 | ./client_udt/client_udt 22252 120.26.200.117 23456 1400 >/dev/null &
36 | ./client_udt/client_udt 22253 120.26.200.117 23456 1400 >/dev/null &
37 | ./client_udt/client_udt 22254 120.26.200.117 23456 1400 >/dev/null &
38 | ./client_udt/client_udt 22255 120.26.200.117 23456 1400 >/dev/null &
39 | ./client_udt/client_udt 22256 120.26.200.117 23456 1400 >/dev/null &
40 | ./client_udt/client_udt 22257 120.26.200.117 23456 1400 >/dev/null &
41 | ./client_udt/client_udt 22258 120.26.200.117 23456 1400 >/dev/null &
42 | ./client_udt/client_udt 22259 120.26.200.117 23456 1400 >/dev/null &
43 |
44 | ./client_udt/client_udt 22260 120.26.200.117 23456 1400 >/dev/null &
45 | ./client_udt/client_udt 22261 120.26.200.117 23456 1400 >/dev/null &
46 | ./client_udt/client_udt 22262 120.26.200.117 23456 1400 >/dev/null &
47 | ./client_udt/client_udt 22263 120.26.200.117 23456 1400 >/dev/null &
48 | ./client_udt/client_udt 22264 120.26.200.117 23456 1400 >/dev/null &
49 | ./client_udt/client_udt 22265 120.26.200.117 23456 1400 >/dev/null &
50 | ./client_udt/client_udt 22266 120.26.200.117 23456 1400 >/dev/null &
51 | ./client_udt/client_udt 22267 120.26.200.117 23456 1400 >/dev/null &
52 | ./client_udt/client_udt 22268 120.26.200.117 23456 1400 >/dev/null &
53 | ./client_udt/client_udt 22269 120.26.200.117 23456 1400 >/dev/null &
54 | ./client_udt/client_udt 22270 120.26.200.117 23456 1400 >/dev/null &
55 | ./client_udt/client_udt 22271 120.26.200.117 23456 1400 >/dev/null &
56 | ./client_udt/client_udt 22272 120.26.200.117 23456 1400 >/dev/null &
57 | ./client_udt/client_udt 22273 120.26.200.117 23456 1400 >/dev/null &
58 | ./client_udt/client_udt 22274 120.26.200.117 23456 1400 >/dev/null &
59 | ./client_udt/client_udt 22275 120.26.200.117 23456 1400 >/dev/null &
60 | ./client_udt/client_udt 22276 120.26.200.117 23456 1400 >/dev/null &
61 | ./client_udt/client_udt 22277 120.26.200.117 23456 1400 >/dev/null &
62 | ./client_udt/client_udt 22278 120.26.200.117 23456 1400 >/dev/null &
63 | ./client_udt/client_udt 22279 120.26.200.117 23456 1400 >/dev/null &
64 |
--------------------------------------------------------------------------------
/launcher_clients2.sh:
--------------------------------------------------------------------------------
1 |
2 | ./client_udt/client_udt 22320 120.26.200.117 23456 1400 &
3 | ./client_udt/client_udt 22321 120.26.200.117 23456 1400 &
4 | ./client_udt/client_udt 22322 120.26.200.117 23456 1400 &
5 | ./client_udt/client_udt 22323 120.26.200.117 23456 1400 &
6 | ./client_udt/client_udt 22324 120.26.200.117 23456 1400 &
7 | ./client_udt/client_udt 22325 120.26.200.117 23456 1400 &
8 | ./client_udt/client_udt 22326 120.26.200.117 23456 1400 &
9 | ./client_udt/client_udt 22327 120.26.200.117 23456 1400 &
10 | ./client_udt/client_udt 22328 120.26.200.117 23456 1400 &
11 | ./client_udt/client_udt 22329 120.26.200.117 23456 1400 &
12 | ./client_udt/client_udt 22330 120.26.200.117 23456 1400 &
13 | ./client_udt/client_udt 22331 120.26.200.117 23456 1400 &
14 | ./client_udt/client_udt 22332 120.26.200.117 23456 1400 &
15 | ./client_udt/client_udt 22333 120.26.200.117 23456 1400 &
16 | ./client_udt/client_udt 22334 120.26.200.117 23456 1400 &
17 | ./client_udt/client_udt 22335 120.26.200.117 23456 1400 &
18 | ./client_udt/client_udt 22336 120.26.200.117 23456 1400 &
19 | ./client_udt/client_udt 22337 120.26.200.117 23456 1400 &
20 | ./client_udt/client_udt 22338 120.26.200.117 23456 1400 &
21 | ./client_udt/client_udt 22339 120.26.200.117 23456 1400 &
22 |
23 | ./client_udt/client_udt 22340 120.26.200.117 23456 1400 &
24 | ./client_udt/client_udt 22341 120.26.200.117 23456 1400 &
25 | ./client_udt/client_udt 22342 120.26.200.117 23456 1400 &
26 | ./client_udt/client_udt 22343 120.26.200.117 23456 1400 &
27 | ./client_udt/client_udt 22344 120.26.200.117 23456 1400 &
28 | ./client_udt/client_udt 22345 120.26.200.117 23456 1400 &
29 | ./client_udt/client_udt 22346 120.26.200.117 23456 1400 &
30 | ./client_udt/client_udt 22347 120.26.200.117 23456 1400 &
31 | ./client_udt/client_udt 22348 120.26.200.117 23456 1400 &
32 | ./client_udt/client_udt 22349 120.26.200.117 23456 1400 &
33 | ./client_udt/client_udt 22350 120.26.200.117 23456 1400 &
34 | ./client_udt/client_udt 22351 120.26.200.117 23456 1400 &
35 | ./client_udt/client_udt 22352 120.26.200.117 23456 1400 &
36 | ./client_udt/client_udt 22353 120.26.200.117 23456 1400 &
37 | ./client_udt/client_udt 22354 120.26.200.117 23456 1400 &
38 | ./client_udt/client_udt 22355 120.26.200.117 23456 1400 &
39 | ./client_udt/client_udt 22356 120.26.200.117 23456 1400 &
40 | ./client_udt/client_udt 22357 120.26.200.117 23456 1400 &
41 | ./client_udt/client_udt 22358 120.26.200.117 23456 1400 &
42 | ./client_udt/client_udt 22359 120.26.200.117 23456 1400 &
43 |
44 | ./client_udt/client_udt 22360 120.26.200.117 23456 1400 &
45 | ./client_udt/client_udt 22361 120.26.200.117 23456 1400 &
46 | ./client_udt/client_udt 22362 120.26.200.117 23456 1400 &
47 | ./client_udt/client_udt 22363 120.26.200.117 23456 1400 &
48 | ./client_udt/client_udt 22364 120.26.200.117 23456 1400 &
49 | ./client_udt/client_udt 22365 120.26.200.117 23456 1400 &
50 | ./client_udt/client_udt 22366 120.26.200.117 23456 1400 &
51 | ./client_udt/client_udt 22367 120.26.200.117 23456 1400 &
52 | ./client_udt/client_udt 22368 120.26.200.117 23456 1400 &
53 | ./client_udt/client_udt 22369 120.26.200.117 23456 1400 &
54 | ./client_udt/client_udt 22370 120.26.200.117 23456 1400 &
55 | ./client_udt/client_udt 22371 120.26.200.117 23456 1400 &
56 | ./client_udt/client_udt 22372 120.26.200.117 23456 1400 &
57 | ./client_udt/client_udt 22373 120.26.200.117 23456 1400 &
58 | ./client_udt/client_udt 22374 120.26.200.117 23456 1400 &
59 | ./client_udt/client_udt 22375 120.26.200.117 23456 1400 &
60 | ./client_udt/client_udt 22376 120.26.200.117 23456 1400 &
61 | ./client_udt/client_udt 22377 120.26.200.117 23456 1400 &
62 | ./client_udt/client_udt 22378 120.26.200.117 23456 1400 &
63 | ./client_udt/client_udt 22379 120.26.200.117 23456 1400 &
64 |
--------------------------------------------------------------------------------
/launcher_clients3.sh:
--------------------------------------------------------------------------------
1 |
2 | ./client_udt/client_udt 22420 120.26.200.117 23456 1400 &
3 | ./client_udt/client_udt 22421 120.26.200.117 23456 1400 &
4 | ./client_udt/client_udt 22422 120.26.200.117 23456 1400 &
5 | ./client_udt/client_udt 22423 120.26.200.117 23456 1400 &
6 | ./client_udt/client_udt 22424 120.26.200.117 23456 1400 &
7 | ./client_udt/client_udt 22425 120.26.200.117 23456 1400 &
8 | ./client_udt/client_udt 22426 120.26.200.117 23456 1400 &
9 | ./client_udt/client_udt 22427 120.26.200.117 23456 1400 &
10 | ./client_udt/client_udt 22428 120.26.200.117 23456 1400 &
11 | ./client_udt/client_udt 22429 120.26.200.117 23456 1400 &
12 | ./client_udt/client_udt 22430 120.26.200.117 23456 1400 &
13 | ./client_udt/client_udt 22431 120.26.200.117 23456 1400 &
14 | ./client_udt/client_udt 22432 120.26.200.117 23456 1400 &
15 | ./client_udt/client_udt 22433 120.26.200.117 23456 1400 &
16 | ./client_udt/client_udt 22434 120.26.200.117 23456 1400 &
17 | ./client_udt/client_udt 22435 120.26.200.117 23456 1400 &
18 | ./client_udt/client_udt 22436 120.26.200.117 23456 1400 &
19 | ./client_udt/client_udt 22437 120.26.200.117 23456 1400 &
20 | ./client_udt/client_udt 22438 120.26.200.117 23456 1400 &
21 | ./client_udt/client_udt 22439 120.26.200.117 23456 1400 &
22 |
23 | ./client_udt/client_udt 22440 120.26.200.117 23456 1400 &
24 | ./client_udt/client_udt 22441 120.26.200.117 23456 1400 &
25 | ./client_udt/client_udt 22442 120.26.200.117 23456 1400 &
26 | ./client_udt/client_udt 22443 120.26.200.117 23456 1400 &
27 | ./client_udt/client_udt 22444 120.26.200.117 23456 1400 &
28 | ./client_udt/client_udt 22445 120.26.200.117 23456 1400 &
29 | ./client_udt/client_udt 22446 120.26.200.117 23456 1400 &
30 | ./client_udt/client_udt 22447 120.26.200.117 23456 1400 &
31 | ./client_udt/client_udt 22448 120.26.200.117 23456 1400 &
32 | ./client_udt/client_udt 22449 120.26.200.117 23456 1400 &
33 | ./client_udt/client_udt 22450 120.26.200.117 23456 1400 &
34 | ./client_udt/client_udt 22451 120.26.200.117 23456 1400 &
35 | ./client_udt/client_udt 22452 120.26.200.117 23456 1400 &
36 | ./client_udt/client_udt 22453 120.26.200.117 23456 1400 &
37 | ./client_udt/client_udt 22454 120.26.200.117 23456 1400 &
38 | ./client_udt/client_udt 22455 120.26.200.117 23456 1400 &
39 | ./client_udt/client_udt 22456 120.26.200.117 23456 1400 &
40 | ./client_udt/client_udt 22457 120.26.200.117 23456 1400 &
41 | ./client_udt/client_udt 22458 120.26.200.117 23456 1400 &
42 | ./client_udt/client_udt 22459 120.26.200.117 23456 1400 &
43 |
44 | ./client_udt/client_udt 22460 120.26.200.117 23456 1400 &
45 | ./client_udt/client_udt 22461 120.26.200.117 23456 1400 &
46 | ./client_udt/client_udt 22462 120.26.200.117 23456 1400 &
47 | ./client_udt/client_udt 22463 120.26.200.117 23456 1400 &
48 | ./client_udt/client_udt 22464 120.26.200.117 23456 1400 &
49 | ./client_udt/client_udt 22465 120.26.200.117 23456 1400 &
50 | ./client_udt/client_udt 22466 120.26.200.117 23456 1400 &
51 | ./client_udt/client_udt 22467 120.26.200.117 23456 1400 &
52 | ./client_udt/client_udt 22468 120.26.200.117 23456 1400 &
53 | ./client_udt/client_udt 22469 120.26.200.117 23456 1400 &
54 | ./client_udt/client_udt 22470 120.26.200.117 23456 1400 &
55 | ./client_udt/client_udt 22471 120.26.200.117 23456 1400 &
56 | ./client_udt/client_udt 22472 120.26.200.117 23456 1400 &
57 | ./client_udt/client_udt 22473 120.26.200.117 23456 1400 &
58 | ./client_udt/client_udt 22474 120.26.200.117 23456 1400 &
59 | ./client_udt/client_udt 22475 120.26.200.117 23456 1400 &
60 | ./client_udt/client_udt 22476 120.26.200.117 23456 1400 &
61 | ./client_udt/client_udt 22477 120.26.200.117 23456 1400 &
62 | ./client_udt/client_udt 22478 120.26.200.117 23456 1400 &
63 | ./client_udt/client_udt 22479 120.26.200.117 23456 1400 &
64 |
--------------------------------------------------------------------------------
/launcher_clients4.sh:
--------------------------------------------------------------------------------
1 |
2 | ./client_udt/client_udt 22520 120.26.200.117 23456 1400 &
3 | ./client_udt/client_udt 22521 120.26.200.117 23456 1400 &
4 | ./client_udt/client_udt 22522 120.26.200.117 23456 1400 &
5 | ./client_udt/client_udt 22523 120.26.200.117 23456 1400 &
6 | ./client_udt/client_udt 22524 120.26.200.117 23456 1400 &
7 | ./client_udt/client_udt 22525 120.26.200.117 23456 1400 &
8 | ./client_udt/client_udt 22526 120.26.200.117 23456 1400 &
9 | ./client_udt/client_udt 22527 120.26.200.117 23456 1400 &
10 | ./client_udt/client_udt 22528 120.26.200.117 23456 1400 &
11 | ./client_udt/client_udt 22529 120.26.200.117 23456 1400 &
12 | ./client_udt/client_udt 22530 120.26.200.117 23456 1400 &
13 | ./client_udt/client_udt 22531 120.26.200.117 23456 1400 &
14 | ./client_udt/client_udt 22532 120.26.200.117 23456 1400 &
15 | ./client_udt/client_udt 22533 120.26.200.117 23456 1400 &
16 | ./client_udt/client_udt 22534 120.26.200.117 23456 1400 &
17 | ./client_udt/client_udt 22535 120.26.200.117 23456 1400 &
18 | ./client_udt/client_udt 22536 120.26.200.117 23456 1400 &
19 | ./client_udt/client_udt 22537 120.26.200.117 23456 1400 &
20 | ./client_udt/client_udt 22538 120.26.200.117 23456 1400 &
21 | ./client_udt/client_udt 22539 120.26.200.117 23456 1400 &
22 |
23 | ./client_udt/client_udt 22540 120.26.200.117 23456 1400 &
24 | ./client_udt/client_udt 22541 120.26.200.117 23456 1400 &
25 | ./client_udt/client_udt 22542 120.26.200.117 23456 1400 &
26 | ./client_udt/client_udt 22543 120.26.200.117 23456 1400 &
27 | ./client_udt/client_udt 22544 120.26.200.117 23456 1400 &
28 | ./client_udt/client_udt 22545 120.26.200.117 23456 1400 &
29 | ./client_udt/client_udt 22546 120.26.200.117 23456 1400 &
30 | ./client_udt/client_udt 22547 120.26.200.117 23456 1400 &
31 | ./client_udt/client_udt 22548 120.26.200.117 23456 1400 &
32 | ./client_udt/client_udt 22549 120.26.200.117 23456 1400 &
33 | ./client_udt/client_udt 22550 120.26.200.117 23456 1400 &
34 | ./client_udt/client_udt 22551 120.26.200.117 23456 1400 &
35 | ./client_udt/client_udt 22552 120.26.200.117 23456 1400 &
36 | ./client_udt/client_udt 22553 120.26.200.117 23456 1400 &
37 | ./client_udt/client_udt 22554 120.26.200.117 23456 1400 &
38 | ./client_udt/client_udt 22555 120.26.200.117 23456 1400 &
39 | ./client_udt/client_udt 22556 120.26.200.117 23456 1400 &
40 | ./client_udt/client_udt 22557 120.26.200.117 23456 1400 &
41 | ./client_udt/client_udt 22558 120.26.200.117 23456 1400 &
42 | ./client_udt/client_udt 22559 120.26.200.117 23456 1400 &
43 |
44 | ./client_udt/client_udt 22560 120.26.200.117 23456 1400 &
45 | ./client_udt/client_udt 22561 120.26.200.117 23456 1400 &
46 | ./client_udt/client_udt 22562 120.26.200.117 23456 1400 &
47 | ./client_udt/client_udt 22563 120.26.200.117 23456 1400 &
48 | ./client_udt/client_udt 22564 120.26.200.117 23456 1400 &
49 | ./client_udt/client_udt 22565 120.26.200.117 23456 1400 &
50 | ./client_udt/client_udt 22566 120.26.200.117 23456 1400 &
51 | ./client_udt/client_udt 22567 120.26.200.117 23456 1400 &
52 | ./client_udt/client_udt 22568 120.26.200.117 23456 1400 &
53 | ./client_udt/client_udt 22569 120.26.200.117 23456 1400 &
54 | ./client_udt/client_udt 22570 120.26.200.117 23456 1400 &
55 | ./client_udt/client_udt 22571 120.26.200.117 23456 1400 &
56 | ./client_udt/client_udt 22572 120.26.200.117 23456 1400 &
57 | ./client_udt/client_udt 22573 120.26.200.117 23456 1400 &
58 | ./client_udt/client_udt 22574 120.26.200.117 23456 1400 &
59 | ./client_udt/client_udt 22575 120.26.200.117 23456 1400 &
60 | ./client_udt/client_udt 22576 120.26.200.117 23456 1400 &
61 | ./client_udt/client_udt 22577 120.26.200.117 23456 1400 &
62 | ./client_udt/client_udt 22578 120.26.200.117 23456 1400 &
63 | ./client_udt/client_udt 22579 120.26.200.117 23456 1400 &
64 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | This is a patch for UDT 4.10 version.
2 | This patch is for UDT epoll api. Because UDT epoll api has major bug.
3 |
4 | And it is a example for UDT epoll api also.
5 | UDT - udt.sourceforge.net
6 |
7 | And it is a bench mark test. You can see the bench mark test in bench_mark.md.
8 |
9 | ### Build:
10 | 1. making gcc version >= 4.8
11 | 2. modify the OS and ARCH in allmake.sh.
12 | 3. $ . allmake.sh
13 |
14 |
15 | ### Run test:
16 | server/server 127.0.0.1 12345
17 | client_epoll/client_epoll 22222 127.0.0.1 12345 1400 2>>./state.log
18 | or sh launcher_clients.sh
19 |
20 |
21 |
22 | ### Compile for cppunit test
23 | Install cppunit
24 | * download from http://nchc.dl.sourceforge.net/project/cppunit/cppunit/1.12.1/cppunit-1.12.1.tar.gz
25 | or you can use the pack in install_pack folder.
26 | * unpack it. cp cppunit-1.12.1 folder to the folder of duoduo project.
27 | * $ cd cppunit-1.12.1
28 | * $ ./configure
29 | * $ make
30 |
31 |
32 |
33 | Other notes:
34 | 1. The version of udt4 in the project is 4.10.
35 | -- The 4.11 version has a bug that can't be fixed:
36 | The UDT::epoll_wait always return with the situation of all socket need read.
37 | http://sourceforge.net/p/udt/discussion/393036/thread/56c105fe/
38 | http://sourceforge.net/p/udt/discussion/852996/thread/88d8bee5/
39 | -- You can test 4.11 version's bug by change branch to udt4.11_with_bug - $ git checkout udt4.11_with_bug
40 |
41 | 2 . udt4 in this project is coming from https://github.com/LabAdvComp/UDR. It fixed some bug by LabAdvComp. And I made some patch too.
42 |
43 | 3. the meaning of state.log
44 | . - epoll_wait timeout return. means no socket prepare.
45 | N - send: socket is non-blocking (UDT_SNDSYN = false) but no buffer space is available.
46 | R - remove write event to socket
47 | A - add write event to socket
48 | B - epoll busy. sleep for stop add more msg to send buf.
49 |
--------------------------------------------------------------------------------
/server/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | #include "udt_server.h"
10 |
11 | int main(int argc, char* argv[])
12 | {
13 | try
14 | {
15 | // Check command line arguments.
16 | if (argc != 3)
17 | {
18 | std::cerr << "Usage: server_udt \n";
19 | std::cerr << " For IPv4, try:\n";
20 | std::cerr << " battle_server 0.0.0.0 80\n";
21 | std::cerr << " For IPv6, try:\n";
22 | std::cerr << " battle_server 0::0 80\n";
23 | return 1;
24 | }
25 | }
26 | catch (std::exception& e)
27 | {
28 | std::cerr << "exception: " << e.what() << "\n";
29 | }
30 |
31 | std::cout << "run battle_server_udt on " << argv[1] << ':' << argv[2] << std::endl;
32 |
33 | //ignore SIGPIPE
34 | sigset_t ps;
35 | sigemptyset(&ps);
36 | sigaddset(&ps, SIGPIPE);
37 | pthread_sigmask(SIG_BLOCK, &ps, NULL);
38 |
39 | UDTServer server;
40 | server.Run(std::atoi(argv[2]));
41 | return 1;
42 | }
43 |
--------------------------------------------------------------------------------
/server_udt/send_msg_buf.cpp:
--------------------------------------------------------------------------------
1 | //#include
2 | //#include
3 | //#include
4 | //#include
5 |
6 | //#include "test_util.h"
7 | #include "send_msg_buf.h"
8 |
9 |
10 | const std::queue& SendMsgBuf::GetMsgQueue(const UDTSOCKET& sock) const
11 | {
12 | static std::queue empty_msg_buf;
13 | auto iter = send_msg_buff_.find(sock);
14 | if (iter == send_msg_buff_.end())
15 | return empty_msg_buf;
16 | return iter->second;
17 | }
18 |
19 | bool SendMsgBuf::HasMsg(const UDTSOCKET& sock) const
20 | {
21 | auto iter = send_msg_buff_.find(sock);
22 | if (iter != send_msg_buff_.end())
23 | return iter->second.size() > 0;
24 | return false;
25 | }
26 |
27 | msg_ptr_t SendMsgBuf::PeekFrontMsg(const UDTSOCKET& sock) const
28 | {
29 | auto iter = send_msg_buff_.find(sock);
30 | if (iter != send_msg_buff_.end() && iter->second.size() > 0)
31 | return iter->second.front();
32 | return msg_ptr_t();
33 | }
34 |
35 | void SendMsgBuf::PopMsg(const UDTSOCKET& sock)
36 | {
37 | auto iter = send_msg_buff_.find(sock);
38 | if (iter != send_msg_buff_.end())
39 | {
40 | if (iter->second.size() > 0)
41 | iter->second.pop();
42 | if (iter->second.size() == 0)
43 | send_msg_buff_.erase(iter);
44 | }
45 | }
46 |
47 | void SendMsgBuf::AddMsg(const UDTSOCKET& sock, const msg_ptr_t& ptr)
48 | {
49 | auto iter = send_msg_buff_.find(sock);
50 | if (iter != send_msg_buff_.end())
51 | iter->second.push(ptr);
52 | else
53 | {
54 | std::queue msg_queue;
55 | msg_queue.push(ptr);
56 | send_msg_buff_[sock] = msg_queue;
57 | }
58 | }
59 |
60 | void SendMsgBuf::CleanMsg(const UDTSOCKET& sock)
61 | {
62 | auto iter = send_msg_buff_.find(sock);
63 | if (iter != send_msg_buff_.end())
64 | send_msg_buff_.erase(iter);
65 | }
66 |
67 | void SendMsgBuf::CleanAllMsg(void)
68 | {
69 | send_msg_buff_.clear();
70 | }
71 |
--------------------------------------------------------------------------------
/server_udt/send_msg_buf.h:
--------------------------------------------------------------------------------
1 | #ifndef __UDT_SEND_MSG_BUF_H_
2 | #define __UDT_SEND_MSG_BUF_H_
3 |
4 | #include "udt_epoll_def.h"
5 | #include
6 | #include
7 |
8 | class SendMsgBuf
9 | {
10 | public:
11 | SendMsgBuf() {};
12 |
13 | const std::queue& GetMsgQueue(const UDTSOCKET& sock) const;
14 |
15 | bool HasMsg(const UDTSOCKET& sock) const;
16 |
17 | // only peek one msg. not remove it.
18 | // if there is no msg. return empty msg_ptr_t.
19 | msg_ptr_t PeekFrontMsg(const UDTSOCKET& sock) const;
20 |
21 | // remove one msg at front.
22 | void PopMsg(const UDTSOCKET& sock);
23 |
24 | void AddMsg(const UDTSOCKET& sock, const msg_ptr_t& ptr);
25 |
26 | void CleanMsg(const UDTSOCKET& sock);
27 |
28 | void CleanAllMsg(void);
29 |
30 | private:
31 |
32 | private:
33 | std::map > send_msg_buff_;
34 | };
35 |
36 | #endif // __UDT_SEND_MSG_BUF_H_
37 |
--------------------------------------------------------------------------------
/server_udt/send_msg_ctrl.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | //#include
5 | //#include
6 |
7 | #include
8 |
9 | #include "send_msg_ctrl.h"
10 |
11 | static int event_with_write = UDT_EPOLL_IN | UDT_EPOLL_ERR | UDT_EPOLL_OUT;
12 | static int event_only_read = UDT_EPOLL_IN | UDT_EPOLL_ERR;
13 |
14 | void SendMsgCtrl::TrySendMsg(const std::set& writefds)
15 | {
16 | for (const UDTSOCKET& sock : writefds)
17 | {
18 | TrySendMsgOfOneSock(sock);
19 | }
20 | }
21 |
22 | void SendMsgCtrl::TrySendMsgOfOneSock(const UDTSOCKET& sock)
23 | {
24 | while (true)
25 | {
26 | msg_ptr_t msg = send_msg_buf_.PeekFrontMsg(sock);
27 |
28 | // no more msg need send.
29 | if (msg == NULL)
30 | {
31 | TryRemoveWriteEvent(sock);
32 | return;
33 | }
34 |
35 | // do send
36 | {
37 | int send_ret = UDT::sendmsg(sock, msg->c_str(), msg->size(), -1, true);
38 | if (UDT::ERROR == send_ret)
39 | {
40 | CUDTException& lasterror = UDT::getlasterror();
41 | const int error_code = lasterror.getErrorCode();
42 |
43 | // no buffer space is available.
44 | if (error_code == CUDTException::EASYNCSND)
45 | {
46 | std::cerr << "N"; std::cerr.flush();
47 | return; // try send at next epoll return
48 | }
49 |
50 | // badly case. do disconnect thing. need remove socket from epoll.
51 | HandleSendMsgError(sock, lasterror);
52 | return;
53 | }
54 |
55 | // send succ, pop this msg from queue, then continue sending next msg.
56 | assert(static_cast(send_ret) == msg->size());
57 | send_msg_buf_.PopMsg(sock);
58 | continue;
59 | }
60 | }
61 | }
62 |
63 | void SendMsgCtrl::HandleSendMsgError(const UDTSOCKET& sock, CUDTException& lasterror)
64 | {
65 | const int error_code = lasterror.getErrorCode();
66 | std::cout << "UDT sendmsg disconnect: " << error_code << ' ' << lasterror.getErrorMessage() << std::endl;
67 |
68 | UDT::epoll_remove_usock(udt_eid_, sock);
69 | CleanMsg(sock);
70 | events_with_write_.erase(sock);
71 | }
72 |
73 | void SendMsgCtrl::AddMsgToSendBuf(const UDTSOCKET& sock, const msg_ptr_t& msg)
74 | {
75 | send_msg_buf_.AddMsg(sock, msg);
76 | if (!IsWriteEventAdd(sock))
77 | AddWriteEvent(sock);
78 | }
79 |
80 | void SendMsgCtrl::CleanAll(void)
81 | {
82 | }
83 |
84 | void SendMsgCtrl::CleanMsg(const UDTSOCKET& sock)
85 | {
86 | send_msg_buf_.CleanMsg(sock);
87 | }
88 |
89 |
90 | bool SendMsgCtrl::IsWriteEventAdd(const UDTSOCKET& sock) const
91 | {
92 | return events_with_write_.find(sock) != events_with_write_.end();
93 | }
94 |
95 | void SendMsgCtrl::AddWriteEvent(const UDTSOCKET& sock)
96 | {
97 | events_with_write_.insert(sock);
98 | std::cerr << "A"; std::cerr.flush();
99 | UDT::epoll_add_usock(udt_eid_, sock, &event_with_write);
100 | }
101 |
102 | void SendMsgCtrl::TryRemoveWriteEvent(const UDTSOCKET& sock)
103 | {
104 | if (IsWriteEventAdd(sock))
105 | {
106 | events_with_write_.erase(sock);
107 | std::cerr << "R"; std::cerr.flush();
108 | UDT::epoll_remove_usock(udt_eid_, sock);
109 | UDT::epoll_add_usock(udt_eid_, sock, &event_only_read);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/server_udt/send_msg_ctrl.h:
--------------------------------------------------------------------------------
1 | #ifndef __UDT_SEND_MSG_CTRL_H_
2 | #define __UDT_SEND_MSG_CTRL_H_
3 |
4 | #include
5 |
6 | #include "send_msg_buf.h"
7 |
8 | class CUDTException;
9 |
10 | class SendMsgCtrl
11 | {
12 | public:
13 | SendMsgCtrl(int udt_eid) : udt_eid_(udt_eid) {};
14 |
15 | void TrySendMsg(const std::set& writefds);
16 | void AddMsgToSendBuf(const UDTSOCKET& sock, const msg_ptr_t& msg);
17 | void CleanAll(void);
18 | void CleanMsg(const UDTSOCKET& sock);
19 |
20 | private:
21 | void TrySendMsgOfOneSock(const UDTSOCKET& sock);
22 | void HandleSendMsgError(const UDTSOCKET& sock, CUDTException& lasterror);
23 |
24 | bool IsWriteEventAdd(const UDTSOCKET& sock) const;
25 | void AddWriteEvent(const UDTSOCKET& sock);
26 | void TryRemoveWriteEvent(const UDTSOCKET& sock);
27 |
28 | private:
29 | int udt_eid_;
30 | std::set events_with_write_; // Recording the udtsockets that is added to write event.
31 | SendMsgBuf send_msg_buf_;
32 | };
33 |
34 | #endif // __UDT_SEND_MSG_CTRL_H_
35 |
--------------------------------------------------------------------------------
/server_udt/test_util.cpp:
--------------------------------------------------------------------------------
1 | #include "test_util.h"
2 | #include
3 |
4 | std::string test_str(const std::string& str_prefix, const size_t str_len)
5 | {
6 | std::ostringstream ostr;
7 | ostr << str_prefix << ':';
8 | std::string str = ostr.str();
9 |
10 | // when len <= prefixLen
11 | // test_str(adfadf, 3) == adf
12 | if (str.size() >= str_len)
13 | {
14 | str.resize(str_len);
15 | return str;
16 | }
17 |
18 | // when len < 20
19 | // test_str(adf, 13) == adfa:67890123
20 | if (str_len < 20)
21 | {
22 | for (size_t i = str.size() + 1; i <= str_len; ++i)
23 | str.push_back(char(((i % 10) + 0x30)));
24 | return str;
25 | }
26 |
27 | // when len >= 20
28 | // test_str(asdf, 45) = asdf:=====(20_56789)(30_56789)12345
29 | {
30 | // asdf:=====
31 | str.resize(10, '=');
32 |
33 | // (20_56789)(30_56789)
34 | while (str.size() + 10 <= str_len)
35 | {
36 | const size_t new_len = str.size() + 10;
37 | std::ostringstream tmp_ostrm;
38 | tmp_ostrm << str << "(" << new_len << '_';
39 | str = tmp_ostrm.str();
40 | for (size_t i = str.size() + 1; i < new_len; ++i)
41 | str.push_back(char(((i % 10) + 0x30)));
42 | str += ')';
43 | }
44 |
45 | // 12345
46 | if (str.size() < str_len)
47 | {
48 | for (size_t i = str.size() + 1; i <= str_len; ++i)
49 | {
50 | char c = ((i % 10) + 0x30);
51 | str.push_back(c);
52 | }
53 | }
54 | return str;
55 | }
56 |
57 | return str;
58 | }
59 |
--------------------------------------------------------------------------------
/server_udt/test_util.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _DD_TEST_UTIL_H__
3 | #define _DD_TEST_UTIL_H__
4 | #include
5 |
6 | // when len <= prefixLen
7 | // test_str(adfadf, 3) == adf
8 | // when len < 20
9 | // test_str(adf, 13) == adfa:67890123
10 | // when len >= 20
11 | // test_str(asdf, 45) = asdf:=====(20_56789)(30_56789)12345
12 | std::string test_str(const std::string& str_prefix, const size_t str_len);
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/server_udt/udt_epoll_def.h:
--------------------------------------------------------------------------------
1 | #ifndef __UDT_EPOLL_DEF_H_
2 | #define __UDT_EPOLL_DEF_H_
3 |
4 | #include
5 | #include
6 |
7 | typedef std::shared_ptr msg_ptr_t;
8 | typedef int UDTSOCKET;
9 |
10 | #endif // __UDT_EPOLL_DEF_H_
11 |
--------------------------------------------------------------------------------
/server_udt/udt_server.h:
--------------------------------------------------------------------------------
1 | #ifndef __UDT_SERVER_H_
2 | #define __UDT_SERVER_H_
3 |
4 | #include
5 |
6 | #include "send_msg_ctrl.h"
7 |
8 | class UDTServer
9 | {
10 | public:
11 | UDTServer(void);
12 | void Run(int listen_port);
13 |
14 | private:
15 | int CreateListenSocket(int port);
16 | int RecvMsg(const UDTSOCKET& sock, bool& bHaveMsgStill);
17 | void HandleReadFds(const std::set& readfds);
18 |
19 | private:
20 | UDTSOCKET listen_sock_;
21 | char udtbuf_[1024 * 100];
22 | size_t udtbuf_recved_len_;
23 | int udt_running_;
24 | int udt_eid_;
25 | std::shared_ptr send_msg_ctrl_ptr_;
26 | };
27 |
28 | #endif
29 |
--------------------------------------------------------------------------------
/udt4/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are
6 | met:
7 |
8 | * Redistributions of source code must retain the above
9 | copyright notice, this list of conditions and the
10 | following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the
13 | above copyright notice, this list of conditions
14 | and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | * Neither the name of the University of Illinois
18 | nor the names of its contributors may be used to
19 | endorse or promote products derived from this
20 | software without specific prior written permission.
21 |
22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 |
--------------------------------------------------------------------------------
/udt4/Makefile:
--------------------------------------------------------------------------------
1 | DIRS = src app
2 | TARGETS = all clean install
3 |
4 | $(TARGETS): %: $(patsubst %, %.%, $(DIRS))
5 |
6 | $(foreach TGT, $(TARGETS), $(patsubst %, %.$(TGT), $(DIRS))):
7 | $(MAKE) -C $(subst ., , $@)
8 |
--------------------------------------------------------------------------------
/udt4/README.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
2 | All Rights Reserved.
3 | Copyright (c) 2011, Google, Inc. All Rights Reserved.
4 |
5 | UDP-based Data Transfer (UDT) Library - version 4
6 | Author: Yunhong Gu [yunhong.gu @ gmail.com]
7 |
8 | UDT version 4 is free software under BSD License. See ./LICENSE.txt.
9 |
10 | ============================================================================
11 |
12 | UDT Website:
13 | http://udt.sf.net
14 | http://sf.net/projects/udt/
15 |
16 |
17 | CONTENT:
18 | ./src: UDT source code
19 | ./app: Example programs
20 | ./doc: UDT documentation (HTML)
21 | ./win: Visual C++ project files for the Windows version of UDT
22 |
23 |
24 | To make:
25 | make -e os=XXX arch=YYY
26 |
27 | XXX: [LINUX(default), BSD, OSX]
28 | YYY: [IA32(default), POWERPC, IA64, AMD64]
29 |
30 | For example, on OS X, you may need to do "make -e os=OSX arch=POWERPC";
31 | on 32-bit i386 Linux system, simply use "make".
32 |
33 | On Windows systems, use the Visual C++ project files in ./win directory.
34 |
35 |
36 | To use UDT in your application:
37 | Read index.htm in ./doc. The documentation is in HTML format and requires your
38 | browser to support JavaScript.
39 |
40 |
41 | Questions? please post to the UDT project forum:
42 | https://sourceforge.net/projects/udt/forums
43 |
--------------------------------------------------------------------------------
/udt4/RELEASE_NOTES.txt:
--------------------------------------------------------------------------------
1 | version 4.10
2 |
3 | added UDT_SNDDATA and UDT_RCVDATA options
4 | fixed a bug that causes unnecessary connection timeout
5 | improved epoll UDT event handling
6 |
7 | version 4.9
8 |
9 | asynchronous close
10 | asynchronous connect
11 | some bug fixes, especially on EPOLL
12 | improved cache code
13 | removed unnecessary NAK (reduced loss retransmission)
14 | receiver side error can unblock a blocked sender
15 |
16 | version 4.8
17 |
18 | fix a bug that may cause seg fault on concurrent close on the same socket
19 | add epoll support
20 | increase the listener's scalability to 100K concurrent connections
21 | fix a bug that may cause accept/select to return positively when an accepted socket is closed immediately after accept returns
22 | fix a bug that may cause connect to fail if the server closes listening socket immediately after accept returns
23 | fix recvfile fstream write status bug (e.g., when disk is full, recvfile should handle properly now)
24 |
25 | version 4.7a
26 |
27 | fix timeout bug introduced in 4.7
28 | initialize CHandShake
29 |
30 | version 4.7
31 |
32 | Fix several related bugs that can cause hang/memory leak/segmentation fault during cleanup()
33 |
--------------------------------------------------------------------------------
/udt4/app/Makefile:
--------------------------------------------------------------------------------
1 | C++ = g++
2 |
3 | ifndef os
4 | os = LINUX
5 | endif
6 |
7 | ifndef arch
8 | arch = IA32
9 | endif
10 |
11 | CCFLAGS = -Wall -D$(os) -I../src -finline-functions -O3
12 |
13 | ifeq ($(arch), IA32)
14 | CCFLAGS += -DIA32 #-mcpu=pentiumpro -march=pentiumpro -mmmx -msse
15 | endif
16 |
17 | ifeq ($(arch), POWERPC)
18 | CCFLAGS += -mcpu=powerpc
19 | endif
20 |
21 | ifeq ($(arch), IA64)
22 | CCFLAGS += -DIA64
23 | endif
24 |
25 | ifeq ($(arch), SPARC)
26 | CCFLAGS += -DSPARC
27 | endif
28 |
29 | LDFLAGS = -L../src -ludt -lstdc++ -lpthread -lm
30 |
31 | ifeq ($(os), UNIX)
32 | LDFLAGS += -lsocket
33 | endif
34 |
35 | ifeq ($(os), SUNOS)
36 | LDFLAGS += -lrt -lsocket
37 | endif
38 |
39 | DIR = $(shell pwd)
40 |
41 | APP = appserver appclient sendfile recvfile test udcat_client udcat_server
42 |
43 | all: $(APP)
44 |
45 | %.o: %.cpp
46 | $(C++) $(CCFLAGS) $< -c
47 |
48 | appserver: appserver.o
49 | $(C++) $^ -o $@ $(LDFLAGS)
50 | appclient: appclient.o
51 | $(C++) $^ -o $@ $(LDFLAGS)
52 | sendfile: sendfile.o
53 | $(C++) $^ -o $@ $(LDFLAGS)
54 | recvfile: recvfile.o
55 | $(C++) $^ -o $@ $(LDFLAGS)
56 | test: test.o
57 | $(C++) $^ -o $@ $(LDFLAGS)
58 | udcat_server: udcat_server.o udcat_common.o
59 | $(C++) $^ -o $@ $(LDFLAGS)
60 | udcat_client: udcat_client.o udcat_common.o
61 | $(C++) $^ -o $@ $(LDFLAGS)
62 |
63 | clean:
64 | rm -f *.o $(APP)
65 |
66 | install:
67 | export PATH=$(DIR):$$PATH
68 |
--------------------------------------------------------------------------------
/udt4/app/appserver.cpp:
--------------------------------------------------------------------------------
1 | #ifndef WIN32
2 | #include
3 | #include
4 | #include
5 | #include
6 | #else
7 | #include
8 | #include
9 | #include
10 | #endif
11 | #include
12 | #include
13 | #include "cc.h"
14 |
15 | using namespace std;
16 |
17 | #ifndef WIN32
18 | void* recvdata(void*);
19 | #else
20 | DWORD WINAPI recvdata(LPVOID);
21 | #endif
22 |
23 |
24 | int main(int argc, char* argv[])
25 | {
26 | if ((1 != argc) && ((2 != argc) || (0 == atoi(argv[1]))))
27 | {
28 | cout << "usage: appserver [server_port]" << endl;
29 | return 0;
30 | }
31 |
32 | // use this function to initialize the UDT library
33 | UDT::startup();
34 |
35 | addrinfo hints;
36 | addrinfo* res;
37 |
38 | memset(&hints, 0, sizeof(struct addrinfo));
39 |
40 | hints.ai_flags = AI_PASSIVE;
41 | hints.ai_family = AF_INET;
42 | hints.ai_socktype = SOCK_STREAM;
43 | //hints.ai_socktype = SOCK_DGRAM;
44 |
45 | string service("9000");
46 | if (2 == argc)
47 | service = argv[1];
48 |
49 | if (0 != getaddrinfo(NULL, service.c_str(), &hints, &res))
50 | {
51 | cout << "illegal port number or port is busy.\n" << endl;
52 | return 0;
53 | }
54 |
55 | UDTSOCKET serv = UDT::socket(res->ai_family, res->ai_socktype, res->ai_protocol);
56 |
57 | // UDT Options
58 | //UDT::setsockopt(serv, 0, UDT_CC, new CCCFactory, sizeof(CCCFactory));
59 | //UDT::setsockopt(serv, 0, UDT_MSS, new int(9000), sizeof(int));
60 | //UDT::setsockopt(serv, 0, UDT_RCVBUF, new int(10000000), sizeof(int));
61 | //UDT::setsockopt(serv, 0, UDP_RCVBUF, new int(10000000), sizeof(int));
62 |
63 | if (UDT::ERROR == UDT::bind(serv, res->ai_addr, res->ai_addrlen))
64 | {
65 | cout << "bind: " << UDT::getlasterror().getErrorMessage() << endl;
66 | return 0;
67 | }
68 |
69 | freeaddrinfo(res);
70 |
71 | cout << "server is ready at port: " << service << endl;
72 |
73 | if (UDT::ERROR == UDT::listen(serv, 10))
74 | {
75 | cout << "listen: " << UDT::getlasterror().getErrorMessage() << endl;
76 | return 0;
77 | }
78 |
79 | sockaddr_storage clientaddr;
80 | int addrlen = sizeof(clientaddr);
81 |
82 | UDTSOCKET recver;
83 |
84 | while (true)
85 | {
86 | if (UDT::INVALID_SOCK == (recver = UDT::accept(serv, (sockaddr*)&clientaddr, &addrlen)))
87 | {
88 | cout << "accept: " << UDT::getlasterror().getErrorMessage() << endl;
89 | return 0;
90 | }
91 |
92 | char clienthost[NI_MAXHOST];
93 | char clientservice[NI_MAXSERV];
94 | getnameinfo((sockaddr *)&clientaddr, addrlen, clienthost, sizeof(clienthost), clientservice, sizeof(clientservice), NI_NUMERICHOST|NI_NUMERICSERV);
95 | cout << "new connection: " << clienthost << ":" << clientservice << endl;
96 |
97 | #ifndef WIN32
98 | pthread_t rcvthread;
99 | pthread_create(&rcvthread, NULL, recvdata, new UDTSOCKET(recver));
100 | pthread_detach(rcvthread);
101 | #else
102 | CreateThread(NULL, 0, recvdata, new UDTSOCKET(recver), 0, NULL);
103 | #endif
104 | }
105 |
106 | UDT::close(serv);
107 |
108 | // use this function to release the UDT library
109 | UDT::cleanup();
110 |
111 | return 1;
112 | }
113 |
114 | #ifndef WIN32
115 | void* recvdata(void* usocket)
116 | #else
117 | DWORD WINAPI recvdata(LPVOID usocket)
118 | #endif
119 | {
120 | UDTSOCKET recver = *(UDTSOCKET*)usocket;
121 | delete (UDTSOCKET*)usocket;
122 |
123 | char* data;
124 | int size = 100000;
125 | data = new char[size];
126 |
127 | while (true)
128 | {
129 | int rsize = 0;
130 | int rs;
131 | while (rsize < size)
132 | {
133 | if (UDT::ERROR == (rs = UDT::recv(recver, data + rsize, size - rsize, 0)))
134 | {
135 | cout << "recv:" << UDT::getlasterror().getErrorMessage() << endl;
136 | break;
137 | }
138 |
139 | rsize += rs;
140 | }
141 |
142 | if (rsize < size)
143 | break;
144 | }
145 |
146 | delete [] data;
147 |
148 | UDT::close(recver);
149 |
150 | #ifndef WIN32
151 | return NULL;
152 | #else
153 | return 0;
154 | #endif
155 | }
156 |
--------------------------------------------------------------------------------
/udt4/app/cc.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class CTCP: public CCC
5 | {
6 | public:
7 | void init()
8 | {
9 | m_bSlowStart = true;
10 | m_issthresh = 83333;
11 |
12 | m_dPktSndPeriod = 0.0;
13 | m_dCWndSize = 2.0;
14 |
15 | setACKInterval(2);
16 | setRTO(1000000);
17 | }
18 |
19 | virtual void onACK(const int& ack)
20 | {
21 | if (ack == m_iLastACK)
22 | {
23 | if (3 == ++ m_iDupACKCount)
24 | DupACKAction();
25 | else if (m_iDupACKCount > 3)
26 | m_dCWndSize += 1.0;
27 | else
28 | ACKAction();
29 | }
30 | else
31 | {
32 | if (m_iDupACKCount >= 3)
33 | m_dCWndSize = m_issthresh;
34 |
35 | m_iLastACK = ack;
36 | m_iDupACKCount = 1;
37 |
38 | ACKAction();
39 | }
40 | }
41 |
42 | virtual void onTimeout()
43 | {
44 | m_issthresh = getPerfInfo()->pktFlightSize / 2;
45 | if (m_issthresh < 2)
46 | m_issthresh = 2;
47 |
48 | m_bSlowStart = true;
49 | m_dCWndSize = 2.0;
50 | }
51 |
52 | protected:
53 | virtual void ACKAction()
54 | {
55 | if (m_bSlowStart)
56 | {
57 | m_dCWndSize += 1.0;
58 |
59 | if (m_dCWndSize >= m_issthresh)
60 | m_bSlowStart = false;
61 | }
62 | else
63 | m_dCWndSize += 1.0/m_dCWndSize;
64 | }
65 |
66 | virtual void DupACKAction()
67 | {
68 | m_bSlowStart = false;
69 |
70 | m_issthresh = getPerfInfo()->pktFlightSize / 2;
71 | if (m_issthresh < 2)
72 | m_issthresh = 2;
73 |
74 | m_dCWndSize = m_issthresh + 3;
75 | }
76 |
77 | protected:
78 | int m_issthresh;
79 | bool m_bSlowStart;
80 |
81 | int m_iDupACKCount;
82 | int m_iLastACK;
83 | };
84 |
85 |
86 | class CUDPBlast: public CCC
87 | {
88 | public:
89 | CUDPBlast()
90 | {
91 | m_dPktSndPeriod = 1000000;
92 | m_dCWndSize = 83333.0;
93 | }
94 |
95 | public:
96 | void setRate(double mbps)
97 | {
98 | m_dPktSndPeriod = (m_iMSS * 8.0) / mbps;
99 | }
100 | };
101 |
--------------------------------------------------------------------------------
/udt4/app/recvfile.cpp:
--------------------------------------------------------------------------------
1 | #ifndef WIN32
2 | #include
3 | #include
4 | #else
5 | #include
6 | #include
7 | #endif
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | using namespace std;
15 |
16 | int main(int argc, char* argv[])
17 | {
18 | if ((argc != 5) || (0 == atoi(argv[2])))
19 | {
20 | cout << "usage: recvfile server_ip server_port remote_filename local_filename" << endl;
21 | return -1;
22 | }
23 |
24 | // use this function to initialize the UDT library
25 | UDT::startup();
26 |
27 | struct addrinfo hints, *peer;
28 |
29 | memset(&hints, 0, sizeof(struct addrinfo));
30 | hints.ai_flags = AI_PASSIVE;
31 | hints.ai_family = AF_INET;
32 | hints.ai_socktype = SOCK_STREAM;
33 |
34 | UDTSOCKET fhandle = UDT::socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol);
35 |
36 | if (0 != getaddrinfo(argv[1], argv[2], &hints, &peer))
37 | {
38 | cout << "incorrect server/peer address. " << argv[1] << ":" << argv[2] << endl;
39 | return -1;
40 | }
41 |
42 | // connect to the server, implict bind
43 | if (UDT::ERROR == UDT::connect(fhandle, peer->ai_addr, peer->ai_addrlen))
44 | {
45 | cout << "connect: " << UDT::getlasterror().getErrorMessage() << endl;
46 | return -1;
47 | }
48 |
49 | freeaddrinfo(peer);
50 |
51 |
52 | // send name information of the requested file
53 | int len = strlen(argv[3]);
54 |
55 | if (UDT::ERROR == UDT::send(fhandle, (char*)&len, sizeof(int), 0))
56 | {
57 | cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;
58 | return -1;
59 | }
60 |
61 | if (UDT::ERROR == UDT::send(fhandle, argv[3], len, 0))
62 | {
63 | cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;
64 | return -1;
65 | }
66 |
67 | // get size information
68 | int64_t size;
69 |
70 | if (UDT::ERROR == UDT::recv(fhandle, (char*)&size, sizeof(int64_t), 0))
71 | {
72 | cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;
73 | return -1;
74 | }
75 |
76 | if (size < 0)
77 | {
78 | cout << "no such file " << argv[3] << " on the server\n";
79 | return -1;
80 | }
81 |
82 | // receive the file
83 | fstream ofs(argv[4], ios::out | ios::binary | ios::trunc);
84 | int64_t recvsize;
85 | int64_t offset = 0;
86 |
87 | if (UDT::ERROR == (recvsize = UDT::recvfile(fhandle, ofs, offset, size)))
88 | {
89 | cout << "recvfile: " << UDT::getlasterror().getErrorMessage() << endl;
90 | return -1;
91 | }
92 |
93 | UDT::close(fhandle);
94 |
95 | ofs.close();
96 |
97 | // use this function to release the UDT library
98 | UDT::cleanup();
99 |
100 | return 0;
101 | }
102 |
--------------------------------------------------------------------------------
/udt4/app/udcat_client.cpp:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | Copyright 2013 Laboratory for Advanced Computing at the University of Chicago
3 |
4 | This file is part of .
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions
16 | and limitations under the License.
17 | *****************************************************************************/
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include "cc.h"
27 | #include "udcat_common.h"
28 |
29 | using std::cerr;
30 | using std::endl;
31 |
32 | int main(int argc, char* argv[])
33 | {
34 | if (argc != 8)
35 | {
36 | cerr << "usage: appclient server_ip server_port use_blast(0 or 1) udt_sendbuff udp_sendbuff mss" << endl;
37 | return 1;
38 | }
39 |
40 | UDT::startup();
41 |
42 | struct addrinfo hints, *local, *peer;
43 |
44 | memset(&hints, 0, sizeof(struct addrinfo));
45 |
46 | hints.ai_flags = AI_PASSIVE;
47 | hints.ai_family = AF_INET;
48 | hints.ai_socktype = SOCK_STREAM;
49 |
50 | if (0 != getaddrinfo(NULL, "9000", &hints, &local))
51 | {
52 | cerr << "incorrect network address.\n" << endl;
53 | return 1;
54 | }
55 |
56 |
57 | UDTSOCKET client = UDT::socket(local->ai_family, local->ai_socktype, local->ai_protocol);
58 |
59 | int blast = atoi(argv[3]);
60 | int udt_sendbuff = atoi(argv[4]);
61 | int udp_sendbuff = atoi(argv[5]);
62 | int mss = atoi(argv[6]);
63 | int blast_rate = atoi(argv[7]);
64 |
65 |
66 | // UDT Options
67 | if (blast)
68 | UDT::setsockopt(client, 0, UDT_CC, new CCCFactory, sizeof(CCCFactory));
69 |
70 | UDT::setsockopt(client, 0, UDT_MSS, &mss, sizeof(int));
71 | UDT::setsockopt(client, 0, UDT_SNDBUF, &udt_sendbuff, sizeof(int));
72 | UDT::setsockopt(client, 0, UDP_SNDBUF, &udp_sendbuff, sizeof(int));
73 |
74 |
75 | freeaddrinfo(local);
76 |
77 | if (0 != getaddrinfo(argv[1], argv[2], &hints, &peer))
78 | {
79 | cerr << "incorrect server/peer address. " << argv[1] << ":" << argv[2] << endl;
80 | return 1;
81 | }
82 |
83 | // connect to the server, implict bind
84 | if (UDT::ERROR == UDT::connect(client, peer->ai_addr, peer->ai_addrlen))
85 | {
86 | cerr << "connect: " << UDT::getlasterror().getErrorMessage() << endl;
87 | return 1;
88 | }
89 |
90 | pthread_t rcvthread;
91 | pthread_create(&rcvthread, NULL, recvdata, new UDTSOCKET(client));
92 | pthread_detach(rcvthread);
93 |
94 | freeaddrinfo(peer);
95 |
96 | if (blast) {
97 | CUDPBlast* cchandle = NULL;
98 | int temp;
99 | UDT::getsockopt(client, 0, UDT_CC, &cchandle, &temp);
100 | if (NULL != cchandle)
101 | cchandle->setRate(blast_rate);
102 | }
103 |
104 | size_t buf_size = udt_sendbuff;
105 | int size;
106 | char* data = NULL;
107 |
108 | while ((size = getline(&data, &buf_size, stdin)) > 0) {
109 | int ssize = 0;
110 | int ss;
111 | while (ssize < size) {
112 | if (UDT::ERROR == (ss = UDT::send(client, data + ssize, size - ssize, 0))) {
113 | cerr << "send:" << UDT::getlasterror().getErrorMessage() << endl;
114 | break;
115 | }
116 |
117 | ssize += ss;
118 | }
119 |
120 | if (ssize < size)
121 | break;
122 | }
123 |
124 | UDT::close(client);
125 |
126 | free(data);
127 |
128 | UDT::cleanup();
129 |
130 | return 0;
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/udt4/app/udcat_common.cpp:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | Copyright 2013 Laboratory for Advanced Computing at the University of Chicago
3 |
4 | This file is part of .
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions
16 | and limitations under the License.
17 | *****************************************************************************/
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include "udcat_common.h"
25 |
26 | using std::cerr;
27 | using std::endl;
28 |
29 | void* recvdata(void* usocket)
30 | {
31 | UDTSOCKET recver = *(UDTSOCKET*)usocket;
32 | delete (UDTSOCKET*)usocket;
33 |
34 | char* data;
35 | int size = BUF_SIZE;
36 | data = new char[size];
37 |
38 | while (true) {
39 | int rs;
40 | if (UDT::ERROR == (rs = UDT::recv(recver, data, size, 0))) {
41 | cerr << "recv:" << UDT::getlasterror().getErrorMessage() << endl;
42 | break;
43 | }
44 |
45 | write(fileno(stdout), data, rs);
46 | }
47 |
48 | delete [] data;
49 |
50 | UDT::close(recver);
51 |
52 | return NULL;
53 | }
54 |
55 |
56 | void* senddata(void* usocket)
57 | {
58 | UDTSOCKET client = *(UDTSOCKET*)usocket;
59 | delete (UDTSOCKET*)usocket;
60 |
61 | char* data = NULL;
62 | size_t buf_size = BUF_SIZE;
63 | int size;
64 |
65 | while ((size = getline(&data, &buf_size, stdin)) > 0) {
66 | int ssize = 0;
67 | int ss;
68 |
69 | while (ssize < size) {
70 | if (UDT::ERROR == (ss = UDT::send(client, data + ssize, size - ssize, 0)))
71 | {
72 | cerr << "send:" << UDT::getlasterror().getErrorMessage() << endl;
73 | break;
74 | }
75 |
76 | ssize += ss;
77 | }
78 |
79 | if (ssize < size)
80 | break;
81 | }
82 |
83 | free(data);
84 |
85 | UDT::close(client);
86 |
87 | return NULL;
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/udt4/app/udcat_common.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | Copyright 2013 Laboratory for Advanced Computing at the University of Chicago
3 |
4 | This file is part of .
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions
16 | and limitations under the License.
17 | *****************************************************************************/
18 |
19 | // this should be maxline size
20 | #define BUF_SIZE 100000
21 |
22 | void* recvdata(void*);
23 |
24 | void* senddata(void*);
25 |
--------------------------------------------------------------------------------
/udt4/app/udcat_server.cpp:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | Copyright 2013 Laboratory for Advanced Computing at the University of Chicago
3 |
4 | This file is part of udr/udt
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions
16 | and limitations under the License.
17 | *****************************************************************************/
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include "cc.h"
26 |
27 | #include "udcat_common.h"
28 |
29 | using std::cerr;
30 | using std::endl;
31 | using std::string;
32 |
33 | void* recvdata(void*);
34 | void* senddata(void*);
35 |
36 | int buffer_size;
37 |
38 | int main(int argc, char* argv[])
39 | {
40 | if (argc != 6) {
41 | cerr << "usage: appserver server_port use_blast(0 or 1) udt_recvbuff "
42 | "udp_recvbuff mss" << endl;
43 | return 1;
44 | }
45 |
46 | UDT::startup();
47 |
48 | addrinfo hints;
49 | addrinfo* res;
50 |
51 | memset(&hints, 0, sizeof(struct addrinfo));
52 |
53 | hints.ai_flags = AI_PASSIVE;
54 | hints.ai_family = AF_INET;
55 | hints.ai_socktype = SOCK_STREAM;
56 |
57 | string service("9000");
58 | if (2 == argc)
59 | service = argv[1];
60 |
61 | if (0 != getaddrinfo(NULL, service.c_str(), &hints, &res)) {
62 | cerr << "illegal port number or port is busy.\n" << endl;
63 | return 1;
64 | }
65 |
66 | UDTSOCKET serv = UDT::socket(res->ai_family, res->ai_socktype, res->ai_protocol);
67 |
68 | int blast = atoi(argv[2]);
69 | int udt_recvbuff = atoi(argv[3]);
70 | int udp_recvbuff = atoi(argv[4]);
71 | int mss = atoi(argv[5]);
72 | buffer_size = udt_recvbuff;
73 |
74 | // UDT Options
75 | if (blast)
76 | UDT::setsockopt(serv, 0, UDT_CC, new CCCFactory, sizeof(CCCFactory));
77 |
78 | UDT::setsockopt(serv, 0, UDT_MSS, &mss, sizeof(int));
79 | UDT::setsockopt(serv, 0, UDT_RCVBUF, &udt_recvbuff, sizeof(int));
80 | UDT::setsockopt(serv, 0, UDP_RCVBUF, &udp_recvbuff, sizeof(int));
81 |
82 |
83 | if (UDT::ERROR == UDT::bind(serv, res->ai_addr, res->ai_addrlen)) {
84 | cerr << "bind: " << UDT::getlasterror().getErrorMessage() << endl;
85 | return 1;
86 | }
87 |
88 | freeaddrinfo(res);
89 |
90 | cerr << "server is ready at port: " << service << endl;
91 |
92 | if (UDT::ERROR == UDT::listen(serv, 10))
93 | {
94 | cerr << "listen: " << UDT::getlasterror().getErrorMessage() << endl;
95 | return 1;
96 | }
97 |
98 | sockaddr_storage clientaddr;
99 | int addrlen = sizeof(clientaddr);
100 |
101 | UDTSOCKET recver;
102 |
103 | while (true) {
104 | if (UDT::INVALID_SOCK == (recver = UDT::accept(serv,
105 | (sockaddr*)&clientaddr, &addrlen))) {
106 |
107 | cerr << "accept: " << UDT::getlasterror().getErrorMessage() << endl;
108 | return 1;
109 | }
110 |
111 | char clienthost[NI_MAXHOST];
112 | char clientservice[NI_MAXSERV];
113 | getnameinfo((sockaddr *)&clientaddr, addrlen, clienthost,
114 | sizeof(clienthost), clientservice, sizeof(clientservice),
115 | NI_NUMERICHOST|NI_NUMERICSERV);
116 |
117 | cerr << "new connection: " << clienthost << ":" << clientservice << endl;
118 |
119 | pthread_t rcvthread;
120 | pthread_t sendthread;
121 | pthread_create(&rcvthread, NULL, recvdata, new UDTSOCKET(recver));
122 | pthread_create(&sendthread, NULL, senddata, new UDTSOCKET(recver));
123 | pthread_detach(rcvthread);
124 | pthread_detach(sendthread);
125 | }
126 |
127 | UDT::close(serv);
128 |
129 | UDT::cleanup();
130 |
131 | return 0;
132 | }
133 |
134 |
--------------------------------------------------------------------------------
/udt4/doc/doc/accept.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | accept
13 | The accept method retrieves an incoming connection.
14 |
15 | UDTSOCKET accept(
16 | UDTSOCKET u ,
17 | struct sockaddr* addr ,
18 | int* addrlen
19 | );
20 |
21 | Parameters
22 |
23 | u
24 | [in] Descriptor identifying a listening socket.
25 | addr
26 | [out] Address of the peer side of the new accepted connection.
27 | addrlen
28 | [out] Length of the addr structure.
29 |
30 |
31 | Return Value
32 | If no error occurs, accept returns the UDT socket descriptor of the new connection; otherwise, it returns
33 | UDT::INVALID_SOCK.
34 | On a successful return, the address of the peer
35 | side of the connection is written into addr , and its length is in addrlen , if the addr parameter is not NULL.
36 | If an error is returned, the error information
37 | can be retrieved by getlasterror . One of the following error can cause an accept error:
38 |
39 |
40 |
41 | Error Name
42 | Error Code
43 | Comment
44 |
45 |
46 | EINVSOCK
47 | 5004
48 | u is an invalid UDT socket.
49 |
50 |
51 | ENOLISTEN
52 | 5006
53 | u is not in the listening state.
54 |
55 |
56 | ERDVNOSERV
57 | 5007
58 | u is set up to support rendezvous connection.
59 |
60 |
61 | EASYNCRCV
62 | 6002
63 | u is non-blocking (UDT_RCVSYN = false) but there is no connection available.
64 |
65 |
66 |
67 | Description
68 | Once a UDT socket is in listening state, it accepts new connections and maintains the pending connections in a queue. An accept call retrieves
69 | the first connection in the queue, removes it from the queue, and returns the associate socket descriptor.
70 | If there is no connections in the queue when accept is called, a blocking socket will wait until a new connection is set up, whereas a
71 | non-blocking socket will return immediately with an error.
72 | The accepted sockets will inherit all proper attributes from the listening socket.
73 |
74 | See Also
75 | listen , connect , setsockopt , getsockopt
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/udt4/doc/doc/cleanup.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | cleanup
13 | The cleanup method releases the UDT library from your application.
14 |
15 | int cleanup(
16 | );
17 |
18 | Parameters
19 |
20 | None.
21 |
22 |
23 | Return Value
24 | If success, 0 is returned; otherwise, UDT::ERROR is returned and specific error information can be retrieved by getlasterror .
25 | In the current version, this method always succeed.
26 | Description
27 | The cleanup method releases the UDT library. All the remaining open connections will be closed. The background garbage collection is closed. However, this method will do nothing if no startup was ever called, or this is a repeated cleanup call.
28 | The method must be called before the application exits, or before the UDT DLL is released, otherwise memory leak could happen.
29 | See Also
30 | startup
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/udt4/doc/doc/close.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | close
13 | The close method closes a UDT connection.
14 |
15 | int close(
16 | UDTSOCKET u
17 | );
18 |
19 | Parameters
20 |
21 | u
22 | [in] Descriptor identifying the socket to close.
23 |
24 |
25 | Return Value
26 | If success, 0 is returned; otherwise, UDT::ERROR is returned and specific error information can be retrieved by getlasterror .
27 |
28 |
29 |
30 | Error Name
31 | Error Code
32 | Comment
33 |
34 |
35 | EINVSOCK
36 | 5004
37 | u is an invalid UDT socket.
38 |
39 |
40 |
41 | Description
42 | The close method gracefully shutdowns the UDT connection and releases all related data structures associated with the UDT socket. If there is no connection associated
43 | with the socket, close simply release the socket resources.
44 | On a blocking socket, if UDT_LINGER is non-zero, the close call will wait until all data in the sending buffer are sent out or the waiting time has exceeded the
45 | expiration time set by UDT_LINGER. However, if UDT_SYNSND is set to false (i.e., non-blocking sending), close will return immediately and any linger data will be sent at background until the linger timer expires.
46 | The closing UDT socket will send a shutdown message to the peer side so that the peer socket will also be closed. This is a best-effort message. If the message is not successfully
47 | delivered, the peer side will also be closed after a time-out. In UDT, shutdown is not supported.
48 | All sockets should be closed if they are not used any more.
49 |
50 | See Also
51 | socket , setsockopt
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/udt4/doc/doc/connect.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | connect
13 | The connect method connects to a server socket (in regular mode) or a peer socket (in rendezvous mode) to set up a UDT connection.
14 |
15 | int connect(
16 | UDTSOCKET u ,
17 | const struct sockaddr* name ,
18 | int* namelen
19 | );
20 |
21 | Parameters
22 |
23 | u
24 | [in] Descriptor identifying a socket.
25 | name
26 | [out] Address of the server or the peer socket.
27 | namelen
28 | [out] Length of the name structure.
29 |
30 |
31 | Return Value
32 | If success, 0 is returned; otherwise, UDT::ERROR is returned and specific error information can be retrieved by getlasterror .
33 |
34 |
35 |
36 | Error Name
37 | Error Code
38 | Comment
39 |
40 |
41 | ENOSERVER
42 | 1001
43 | server or peer socket does not exist, or there is no network connection.
44 |
45 |
46 | ECONNREJ
47 | 1002
48 | the connection request was rejected by the peer.
49 |
50 |
51 | ESECFAIL
52 | 1004
53 | connection was aborted due to possible attacks.
54 |
55 |
56 | ECONNSOCK
57 | 5002
58 | the socket is not allowed to do a connect connect call; it is either in listening state or has been already connected.
59 |
60 |
61 | EINVSOCK
62 | 5004
63 | u is not a valid socket ID.
64 |
65 |
66 | ERDVUNBOUND
67 | 5008
68 | the rendezvous mode has been enable, but bind was not called before connect .
69 |
70 |
71 |
72 | Description
73 | UDT is connection oriented, for both of its SOCK_STREAM and SOCK_DGRAM mode. connect must be called in order to set up a UDT connection. The name parameter is
74 | the address of the server or the peer side. In regular (default) client/server mode, the server side must has called bind and listen . In rendezvous mode,
75 | both sides must call bind and connect to each other at (approximately) the same time. Rendezvous connect may not be used for more than one connections on the same UDP port pair, in which case UDT_REUSEADDR may be set to false.
76 | UDT connect takes at least one round trip to finish. This may become a bottleneck if applications frequently connect and disconnect to the same address.
77 | When UDT_RCVSYN is set to false, the connect call will return immediately and perform the actual connection setup at background. Applications may use epoll to wait for the connect to complete.
78 | When connect fails, the UDT socket can still be used to connect again. However, if the socket was not bound before, it may be bound implicitly, as mentioned above, even
79 | if the connect fails. In addition, in the situation when the connect call fails, the UDT socket will not be automatically released, it is the applications' responsibility to close the socket, if the socket is not needed anymore (e.g., to re-connect).
80 |
81 | See Also
82 | listen , bind
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/udt4/doc/doc/copy.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Copyright & License
11 |
12 | Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois.
13 | All rights reserved.
14 | Redistribution and use in source and binary forms, with or without
15 | modification, are permitted provided that the following conditions are
16 | met:
17 |
18 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
19 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation
20 | and/or other materials provided with the distribution.
21 | Neither the name of the University of Illinois
22 | nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
23 |
24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/udt4/doc/doc/error.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | getlasterror
13 | The getlasterror method the last UDT error within the same thread.
14 |
15 | ERRORINFO& getlasterror(
16 | );
17 |
18 | Parameters
19 |
20 | None.
21 |
22 |
23 | Return Value
24 | The last UDT error within the same thread is retrieved and returned in an ERRORINFO structure. If there is no error, a special SUCCESS code (0) will be
25 | returned. The getlasterror will always succeed. The returned value is a reference to the internal UDT ERRORINFO structure and application may clear it if necessary.
26 |
27 | Description
28 | The getlasterror method reads the last UDT error in the thread where this method is called. The error information is stored in thread specific storage.
29 |
30 | See Also
31 | Error Code List , Error Handling
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/udt4/doc/doc/footer.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | footer
6 |
7 |
8 |
9 |
10 |
11 | Copyright © 2001 - 2011 Yunhong Gu . All rights reserved.
12 | Last modified: Tuesday, February 8, 2011 1:10 PM.
13 |
14 |
15 |
--------------------------------------------------------------------------------
/udt4/doc/doc/function.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | UDT Socket Functions
13 |
14 | The UDT socket functions are contained in the UDT namespace. The methods are listed in the table below:
15 |
16 |
17 |
18 | Method
19 | Fuctionality
20 |
21 |
22 | accept
23 | accept a connection.
24 |
25 |
26 | bind
27 | assign a local name to an unnamed udt socket.
28 |
29 |
30 | cleanup
31 | release the complete UDT library.
32 |
33 |
34 | close
35 | close the opened UDT entity and shutdown the connection.
36 |
37 |
38 | connect
39 | connect to the server or the peer side.
40 |
41 |
42 | epoll
43 | watch for a group of UDT and system sockets for IO events.
44 |
45 |
46 | getlasterror
47 | retrieve last UDT error in the current thread.
48 |
49 |
50 | getpeername
51 | read the address of the peer side of the connection
52 |
53 |
54 | getsockname
55 | read the local address of the UDT socket.
56 |
57 |
58 | getsockopt
59 | read UDT options.
60 |
61 |
62 | listen
63 | enable UDT into listening state and is ready for connection request.
64 |
65 |
66 | perfmon
67 | monitor internal protocol parameters and udt performance.
68 |
69 |
70 | recv
71 | receive data.
72 |
73 |
74 | recvfile
75 | receive data into a file.
76 |
77 |
78 | recvmsg
79 | receive a message.
80 |
81 |
82 | select
83 | wait for a number of UDT sockets to change status.
84 |
85 |
86 | send
87 | send data.
88 |
89 |
90 | sendfile
91 | send a file.
92 |
93 |
94 | sendmsg
95 | send a message.
96 |
97 |
98 | setsockopt
99 | configure UDT options.
100 |
101 |
102 | socket
103 | create a new UDT socket.
104 |
105 |
106 | startup
107 | initialize the UDT library.
108 |
109 |
110 |
111 | See Also
112 | UDT Socket Structures
113 |
114 |
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/udt4/doc/doc/header.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Untitled Document
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/udt4/doc/doc/intro.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT: UDP-based Data Transfer Library - version 4
11 | Yunhong Gu
12 |
13 | Welcome to the UDT4 SDK documentation.
14 | UDT is a high performance data transfer protocol - UDP-based data transfer protocol. It was designed for
15 | data intensive applications over high speed wide area networks, to overcome the efficiency and fairness problems of TCP.
16 | As its name indicates, UDT is built on top of UDP and it provides both reliable data streaming and messaging services.
17 | Visit http://udt.sf.net for most recent news on UDT.
18 |
19 | Check out most current UDT release at SourceForge or from CVS .
20 |
21 | export CVS_RSH=ssh
22 | cvs -d:pserver:anonymous@udt.cvs.sourceforge.net:/cvsroot/udt login
23 | [NOTE: when prompt for password, press the RETURN/ENTER key]
24 | cvs -d:pserver:anonymous@udt.cvs.sourceforge.net:/cvsroot/udt co UDT4
25 |
26 | In this documentation:
27 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/udt4/doc/doc/listen.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | listen
13 | The listen method enables a server UDT entity to wait for clients to connect.
14 |
15 | int list(
16 | UDTSOCKET u
17 | int backlog
18 | );
19 |
20 | Parameters
21 |
22 | u
23 | [in] Descriptor identifying the server socket.
24 | backlog
25 | [in] Maximum number of pending connections.
26 |
27 |
28 | Return Value
29 | If success, 0 is returned; otherwise, UDT::ERROR is returned and specific error information can be retrieved by getlasterror .
30 |
31 |
32 |
33 | Error Name
34 | Error Code
35 | Comment
36 |
37 |
38 | ECONNSOCK
39 | 5002
40 | u is already connected.
41 |
42 |
43 | EINVSOCK
44 | 5004
45 | u is an invalid socket.
46 |
47 |
48 | EUNBOUNDSOCK
49 | 5005
50 | u is not bound.
51 |
52 |
53 | ERDVNOSERV
54 | 5007
55 | u is in rendezvous mode.
56 |
57 |
58 |
59 | Description
60 | The listen method lets a UDT socket enter listening state. The socket must call bind before a listen call. In addition, if the
61 | socket is enable for rendezvous mode, neither listen nor accept can be used on the socket. A UDT socket can call listen more than once,
62 | in which case only the first call is effective, while all subsequent calls will be ignored if the socket is already in listening state.
63 |
64 | See Also
65 | bind , accpet , connect
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/udt4/doc/doc/make.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
13 |
14 |
15 |
16 | Installation Guide
17 | The UDT library is distributed with source code, example applications, and documentation. Currently the source code can be compiled on both Linux and Windows system.
18 |
19 | Here is the content of the distribution:
20 |
21 | ./src : UDT source code
22 | ./app : Example applications
23 | ./doc : UDT documentation
24 | ./win : Visual C++ project files for Windows version of UDT
25 |
26 | The library is in the original source code format without any installation tools, so installation is simply a make command. To make the C++ source code on different platform, the user
27 | needs to explicitly tell make the current operating system and hardware architecture with the "-e" option (except for Windows).
28 | The available operating system options are: LINUX, BSD, and OSX. The available options for hardware architecture are: IA32, IA64, POWERPC, and AMD64.
29 |
30 | The command is in the format:
31 |
32 | make -e os=XXX arch=YYY
33 |
34 | where XXX and YYY are one of the options above. Note that it is case sensitive. There is a default value for Linux on the IA32 architecture, so if UDT is compiled on it, simply use
35 | make.
36 |
37 |
38 |
On Windows, use the Visual Studio .Net project files at ./win directory. It requires Visual C++ 7.0 or above to compile. Windows XP or above is also required under the default setting.
39 | If other Windows compilers are used, you may need to create
40 | your own Makefile or project files. In particular, if you use Visual C++ 6.0 or your system is Windows 2000 or certain embeded Windows systems, please define LEGACY_WIN32 in your Makefile or project files. You may also need to download Windows platform SDK in order to get the <wspiapi.h> header file.
41 | After a successful make, you can begin to use the UDT library. The (only) header file udt.h and the library libudt.a (depending on the target system, libudt.so, libudt.dylib, and udt.dll
42 | may be available) are located in ./src directory.
43 | Proper environment configuration should be set up before using UDT library. For example, if using libudt.so, the library path environment variable must be updated as:
44 |
45 |
46 |
47 | export LD_LIBRARY_PATH=[location of libudt.so, e.g., ../src]:$LD_LIBRARY_PATH
48 |
49 |
50 | On Windows, copy udt.dll to the proper directory.
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/udt4/doc/doc/peername.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | getpeername
13 | The getpeername method retrieves the address informtion of the peer side of a connected UDT socket.
14 |
15 | int getpeername(
16 | UDTSOCKET u ,
17 | struct sockaddr* name ,
18 | int* namelen
19 | );
20 |
21 | Parameters
22 |
23 | u
24 | [in] Descriptor identifying a connected socket.
25 | name
26 | [out] The structure to store the address of the peer.
27 | addrlen
28 | [in, out] pointer to the size of the name structure.
29 |
30 |
31 | Return Value
32 | On success, getlasterror returns 0 and the peer address information is stored in name ; otherwise it returns UDT::ERROR and the specific error information can be
33 | retrieved using getlasterror .
34 |
35 |
36 |
37 | Error Name
38 | Error Code
39 | Comment
40 |
41 |
42 | ENOCONN
43 | 2002
44 | u is not connected.
45 |
46 |
47 | EINVPARAM
48 | 5003
49 | Invalid parameters.
50 |
51 |
52 | EINVSOCK
53 | 5004
54 | u is an invailid UDT socket.
55 |
56 |
57 |
58 | Description
59 | The getpeername retrieves the address of the peer side associated to the connection. The UDT socket must be connected at the time when this method is called. The
60 | namelen must provide the leangth of the name parameter, which should be enough to hold the address information. On return, namelen contains the length of the result.
61 |
62 | See Also
63 | listen , connect , accept
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/udt4/doc/doc/recv.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | recv
13 | The recv method reads certain amount of data into a local memory buffer.
14 |
15 | int recv(
16 | UDTSOCKET u ,
17 | char* buf ,
18 | int len ,
19 | int flags
20 | );
21 |
22 | Parameters
23 |
24 | u
25 | [in] Descriptor identifying a connected socket.
26 | buf
27 | [out] The buffer used to store incoming data.
28 | len
29 | [in] Length of the buffer.
30 | flags
31 | [in] Ignored. For compatibility only.
32 |
33 |
34 | Return Value
35 | On success, recv returns the actual size of received data. Otherwise UDT::ERROR is returned and specific error information can be retrieved by getlasterror . If UDT_RCVTIMEO is set to a positive value, zero will be returned if no data is received before the timer expires.
37 |
38 |
39 |
40 | Error Name
41 | Error Code
42 | Comment
43 |
44 |
45 | ECONNLOST
46 | 2001
47 | connection has been broken and no data left in receiver buffer.
48 |
49 |
50 | ENOCONN
51 | 2002
52 | u is not connected.
53 |
54 |
55 | EINVSOCK
56 | 5004
57 | u is not an valid socket.
58 |
59 |
60 | EDGRAMILL
61 | 5010
62 | cannot use recv in SOCK_DGRAM mode.
63 |
64 |
65 | EASYNCRCV
66 | 6002
67 | u is non-blocking (UDT_RCVSYN = false) but no data is available.
68 |
69 |
70 |
71 | Description
72 | The recv method reads certain amount of data from the protocol buffer. If there is not enough data in the buffer, recv only reads the available data
73 | in the protocol buffer and returns the actual size of data received. However, recv will never read more data than the buffer size indicates by len .
74 | In blocking mode (default), recv waits until there is some data received into the receiver buffer. In non-blocking mode, recv returns immediately and
75 | returns error if no data available.
76 | If UDT_RCVTIMEO is set and the socket is in blocking mode, recv only waits a limited time specified by UDT_RCVTIMEO option. If there is still no data available when
77 | the timer expires, zero will be returned. UDT_RCVTIMEO has no effect for non-blocking socket.
78 |
79 | See Also
80 | select , send , sendfile , recvfile
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/udt4/doc/doc/recvfile.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | recvfile
13 | The recvfile method reads certain amount of data into a local file.
14 |
15 | int64_t recvfile(
16 | UDTSOCKET u ,
17 | fstream& ofs ,
18 | int64_t& offset ,
19 | int64_t size ,
20 | int block = 366000
21 | );
22 |
23 | Parameters
24 |
25 | u
26 | [in] Descriptor identifying a connected socket.
27 | ofs
28 | [in] C++ fstream descriptor for the file to store incoming data.
29 | offset
30 | [in, out] The offset position from where the data is written into the file; after the call returns, this value records the new offset of the write position.
31 | size
32 | [in] The total size to be received.
33 | block
34 | [in] Optional. The size of every data block for file IO.
35 |
36 |
37 | Return Value
38 | On success, recvfile returns the actual size of received data. Otherwise UDT::ERROR is returned and specific error information can be retrieved by getlasterror .
40 |
41 |
42 |
43 | Error Name
44 | Error Code
45 | Comment
46 |
47 |
48 | ECONNLOST
49 | 2001
50 | connection has been broken and no data left in receiver buffer.
51 |
52 |
53 | ENOCONN
54 | 2002
55 | u is not connected.
56 |
57 |
58 | EFILE
59 | 4000
60 | File or disk system errors.
61 |
62 |
63 | EINVSOCK
64 | 5004
65 | u is not an valid socket.
66 |
67 |
68 | EDGRAMILL
69 | 5010
70 | cannot use recvfile in SOCK_DGRAM mode.
71 |
72 |
73 |
74 | Description
75 | The recvfile method reads certain amount of data and write it into a local file. It is always in blocking mode and neither UDT_RCVSYN nor UDT_RCVTIMEO affects this method. The actual size of data to expect must be known before calling recvfile, otherwise deadlock may occur due to insufficient incoming data.
76 | See Also
77 | send , sendfile , recv
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/udt4/doc/doc/recvmsg.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | recvmsg
13 | The recvmsg method receives a valid message.
14 |
15 | int recvmsg(
16 | UDTSOCKET u ,
17 | char* msg ,
18 | int len
19 | );
20 |
21 | Parameters
22 |
23 | u
24 | [in] Descriptor identifying a connected socket.
25 | msg
26 | [out] The buffer used to store incoming message.
27 | len
28 | [in] Length of the buffer.
29 |
30 |
31 | Return Value
32 | On success, recvmsg returns the actual size of received message. Otherwise UDT::ERROR is returned and specific error information can be retrieved by getlasterror . If UDT_RCVTIMEO is set to a positive value, zero will be returned if no message is received before the timer expires.
34 |
35 |
36 |
37 | Error Name
38 | Error Code
39 | Comment
40 |
41 |
42 | ECONNLOST
43 | 2001
44 | connection has been broken and no data left in receiver buffer.
45 |
46 |
47 | ENOCONN
48 | 2002
49 | u is not connected.
50 |
51 |
52 | EINVSOCK
53 | 5004
54 | u is not an valid socket.
55 |
56 |
57 | ESTREAMILL
58 | 5009
59 | cannot use recvmsg in SOCK_STREAM mode.
60 |
61 |
62 | EASYNCRCV
63 | 6002
64 | u is non-blocking (UDT_RCVSYN = false) but no message is available.
65 |
66 |
67 |
68 | Description
69 | The recvmsg method reads a message from the protocol buffer. The UDT socket must be in SOCK_DGRAM mode in order to send or receive messages. Message is the minimum
70 | data unit in this situation. Each recvmsg will read no more than one message, even if the message is smaller than the size of buf and there
71 | are more messages available. On the other hand, if the buf is not enough to hold the first message, only part of the message will be copied into the buffer,
72 | but the message will still be discarded after this recvmsg call.
73 | In blocking mode (default), recvmsg waits until there is a valid message received into the receiver buffer. In non-blocking mode,
74 | recvmsg returns immediately and returns error if no message available.
75 | If UDT_RCVTIMEO is set and the socket is in blocking mode, recvmsg only waits a limited time specified by UDT_RCVTIMEO option. If there is still
76 | no message available when the timer expires, zero will be returned. UDT_RCVTIMEO has no effect for non-blocking socket.
77 |
78 | See Also
79 | select , send
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/udt4/doc/doc/reference.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Reference
11 | This section describes in detail the UDT API, including:
12 |
13 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/udt4/doc/doc/selectex.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
12 |
13 |
14 |
15 | UDT Reference: Functions
16 |
17 | select Ex
18 | The selectEx method queries a group of of UDT sockets for IO status.
19 | Note: selectEx is deprecated. Please use epoll instead, which is far more efficienct.
20 | int selectEx(
21 | std::vector<UDTSOCKET> fds ,
22 | std::vector<UDTSOCKET>* readfds ,
23 | std::vector<UDTSOCKET>* writefds ,
24 | std::vector<UDTSOCKET>* exceptfds ,
25 | const int64_t msTimeOut
26 | );
27 |
28 | Parameters
29 |
30 | fds
31 | [in] the group of UDT socket descriptors to be queried, in a C++ vector.
32 | readfds
33 | [out] Optional pointer to a set of sockets that are ready for recv.
34 | writefds
35 | [out] Optional pointer to a set of sockets that are ready for send.
36 | exceptfds
37 | [out] Optional pointer to a set of sockets that are closed or with a broken connection.
38 | msTimeOut
39 | [in] The time that this function should wait for the status change in the input groups, in milliseconds.
40 |
41 |
42 | Return Value
43 | If any of the read, write, or except group is not empty, selectEx returns the number of UDT sockets that are read for read/write or are broken/closed. If no socket is ready before timeout, zero is
44 | returned. If there is any error, UDT::ERROR is returned and the specific error information can be retrieved using getlasterror . The readfds,writefds and/or
45 | exceptfds will be updated to contain the ready sockets.
46 |
47 |
48 |
49 |
50 | Error Name
51 | Error Code
52 | Comment
53 |
54 |
55 | EINVPARAM
56 | 5003
57 | All three socket sets are NULL or at least one of the socket is invalid.
58 |
59 |
60 |
61 | Description
62 | This function selectEx is an advanced version of select . In contrast to select , selectEx does not modify the input parameter fds , so that applications do not need to replicate or initialize it every time the function is called.
63 | The new function only has one group of input socket descriptors. If a particular event check is not necessary, the corresponding output parameter can be set to NULL. For example, if the application does not care about if a socket is ready for send, the parameter writefds can be NULL.
64 | Finally, selectEx specifies the absolute amount of time to wait, while select requires a clock time in the future to wait until.
65 | Overall, selectEx is more convinient and more efficient.
66 |
67 | See Also
68 | select , epoll
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/udt4/doc/doc/send.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | send
13 | The send method sends out certain amount of data from an application buffer.
14 |
15 | int send(
16 | UDTSOCKET u ,
17 | const char* buf ,
18 | int len ,
19 | int flags
20 | );
21 |
22 | Parameters
23 |
24 | u
25 | [in] Descriptor identifying a connected socket.
26 | buf
27 | [in] The buffer of data to be sent.
28 | len
29 | [in] Length of the buffer.
30 | flags
31 | [in] Ignored. For compatibility only.
32 |
33 |
34 | Return Value
35 | On success, send returns the actual size of data that has been sent. Otherwise UDT::ERROR is returned and specific error information can be retrieved by getlasterror . If UDT_SNDTIMEO is set to a positive value, zero will be returned if no data is sent before the timer expires.
37 |
38 |
39 |
40 | Error Name
41 | Error Code
42 | Comment
43 |
44 |
45 | ECONNLOST
46 | 2001
47 | connection has been broken.
48 |
49 |
50 | ENOCONN
51 | 2002
52 | u is not connected.
53 |
54 |
55 | EINVSOCK
56 | 5004
57 | u is not an valid socket.
58 |
59 |
60 | EDGRAMILL
61 | 5010
62 | cannot use send in SOCK_DGRAM mode.
63 |
64 |
65 | EASYNCSND
66 | 6001
67 | u is non-blocking (UDT_SNDSYN = false) but buffer space is available for sending.
68 |
69 |
70 | EPEERERR
71 | 7000
72 | The peer side has an unrecoverable error and this call has to be cancelled.
73 |
74 |
75 |
76 | Description
77 | The send method sends certain amount of data from the application buffer. If the the size limit of sending buffer queue is reached,
78 | send only sends a portion of the application buffer and returns the actual size of data that has been sent.
79 | In blocking mode (default), send waits until there is some sending buffer space available. In non-blocking mode, send
80 | returns immediately and returns error if the sending queue limit is already limited.
81 | If UDT_SNDTIMEO is set and the socket is in blocking mode, send only waits a limited time specified by UDT_SNDTIMEO option. If there is still no
82 | buffer space available when the timer expires, zero will be returned. UDT_SNDTIMEO has no effect for non-blocking socket.
83 |
84 | See Also
85 | select , send , sendfile , recvfile
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/udt4/doc/doc/sendfile.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | sendfile
13 | The sendfile method sends out part or the whole of a local file.
14 |
15 | int64_t sendfile(
16 | UDTSOCKET u ,
17 | fstream& ifs ,
18 | const int64_t& offset ,
19 | const int64_t size ,
20 | const int block = 7320000
21 | );
22 |
23 | Parameters
24 |
25 | u
26 | [in] Descriptor identifying a connected socket.
27 | ifs
28 | [in] C++ fstream descriptor for the file to read data from.
29 | offset
30 | [in, out] The offset position from where the data is read from the file. After the call returns, this value holds the updated read position.
31 | size
32 | [in] The total size to be sent.
33 | block
34 | [in] Optional. The size of every data block for file IO.
35 |
36 |
37 | Return Value
38 | On success, sendfile returns the actual size of data that has been sent. Otherwise UDT::ERROR is returned and specific error information can be retrieved by
39 | getlasterror .
40 |
41 |
42 |
43 | Error Name
44 | Error Code
45 | Comment
46 |
47 |
48 | ECONNLOST
49 | 2001
50 | connection has been broken.
51 |
52 |
53 | ENOCONN
54 | 2002
55 | u is not connected.
56 |
57 |
58 | EINVOP
59 | 4000
60 | File or disk system errors.
61 |
62 |
63 | EINVSOCK
64 | 5004
65 | u is not an valid socket.
66 |
67 |
68 | EDGRAMILL
69 | 5010
70 | cannot use sendfile in SOCK_DGRAM mode.
71 |
72 |
73 | EPEERERR
74 | 7000
75 | The peer side has an unrecoverable error and this call has to be cancelled.
76 |
77 |
78 |
79 | Description
80 | The sendfile method sends certain amount of out of a local file. It is always in blocking mode an neither UDT_SNDSYN nor UDT_SNDTIMEO affects this method. However, the sendfile method has a streaming semantics same as send .
81 | Note that sendfile does NOT nessesarily require recvfile at the peer side. Sendfile/recvfile and send/recv are orthogonal
82 | UDT methods.
83 |
84 | See Also
85 | send , recv , recvfile
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/udt4/doc/doc/socket.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | socket
13 | The socket method creates a new UDT socket.
14 |
15 | UDTSOCKET socket(
16 | int af ,
17 | int type ,
18 | int protocol
19 | );
20 |
21 | Parameters
22 |
23 | af
24 | [in] IP Family: AF_INET or AF_INET6.
25 | type
26 | [in] Type of the socket: SOCK_STREAM or SOCK_DGRAM.
27 | protocol
28 | [in] Ignored. For compatibility only.
29 |
30 |
31 | Return Value
32 | If no error occurs, socket returns the new UDT socket descriptor; otherwise, it returns UDT::INVALID_SOCK and the error information can be retrieved by getlasterror .
34 |
35 |
36 |
37 | Error Name
38 | Error Code
39 | Comment
40 |
41 |
42 | EINVPARAM
43 | 5003
44 | Invalid parameters.
45 |
46 |
47 |
48 | Description
49 | The socket methods creates a new socket. The is no limits for the number of UDT sockets in one system, as long as there is enough system
50 | resource. UDT supports both IPv4 and IPv6, which can be selected by the af parameter. On the other hand, two socket types are supports in UDT, i.e.,
51 | SOCK_STREAM for data streaming and SOCK_DGRAM for messaging. Note that UDT sockets are connection oriented in all cases.
52 |
53 | See Also
54 | close
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/udt4/doc/doc/sockname.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | getsockname
13 | The getsockname method retrieves the local address associated with a UDT socket.
14 |
15 | int getsockname(
16 | UDTSOCKET u ,
17 | struct sockaddr* name ,
18 | int* namelen
19 | );
20 |
21 | Parameters
22 |
23 | u
24 | [in] Descriptor identifying a connected socket.
25 | name
26 | [out] The structure to store the local address.
27 | addrlen
28 | [in, out] pointer to the size of the name structure.
29 |
30 |
31 | Return Value
32 | On success, getlasterror returns 0 and the local address information is stored in name ; otherwise it returns UDT::ERROR and the specific error information can be
33 | retrieved using getlasterror .
34 |
35 |
36 |
37 | Error Name
38 | Error Code
39 | Comment
40 |
41 |
42 | EINVPARAM
43 | 5003
44 | Invalid parameters.
45 |
46 |
47 | EINVSOCK
48 | 5004
49 | u is an invailid UDT socket.
50 |
51 |
52 | EUNBOUNDSOCK
53 | 5005
54 | u is not bound to a local address yet.
55 |
56 |
57 |
58 | Description
59 | The getsockname retrieves the local address associated with the socket. The UDT socket must be bound explicitly (via bind ) or implicitly (via
60 | connect ), otherwise this method will fail because there is no meaningful address bound to the socket.
61 | If getsockname is called after an explicit bind , but before connect , the IP address returned will be exactly the IP address that is used for bind and it may be 0.0.0.0 if ADDR_ANY is used. If getsockname is called after connect , the IP address returned will be the address that the peer socket sees. In the case when there is a proxy (e.g., NAT), the IP address returned will be the translated address by the proxy, but not a local address. If there is no proxy, the IP address returned will be a local address. In either case, the port number is local (i.e, not the translated proxy port).
62 | Because UDP is connection-less, using getsockname on a UDP port will almost always return 0.0.0.0 as IP address (unless it is bound to an explicit IP) . As a connection oriented protocol, UDT will return a meaningful IP address by getsockname if there is no proxy translation exist.
63 | UDT has no multihoming support yet. When there are multiple local addresses and more than one of them can be routed to the destination address, UDT may not behave properly due to the multi-path effect. In this case, the UDT socket must be explicitly bound to one of the local addresses.
64 | See Also
65 | listen , bind , connect
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/udt4/doc/doc/startup.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | startup
13 | The startup method initializes the UDT library.
14 |
15 | int startup(
16 | );
17 |
18 | Parameters
19 |
20 | None.
21 |
22 |
23 | Return Value
24 | If success, 0 is returned; otherwise, UDT::ERROR is returned and specific error information can be retrieved by getlasterror .
25 | In the current version, this method always succeed.
26 | Description
27 | The startup method initializes the UDT library. In particular, it starts the garbage collection thread. This method must be called before any other UDT calls. Failure to do so may cause memory leak.
28 | If startup is called multiple times in one application, only the first one is effective, while the rest will do nothing.
29 | See Also
30 | cleanup
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/udt4/doc/doc/t-cc.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
12 |
13 |
14 |
15 | UDT Tutorial
16 |
17 | User-defined Congestion Control Algorithm
18 | You can add your own congestion control algorithm into UDT. It is as simple as to define several callback functions that will be triggered on certain events, e.g, when an ACK is
19 | received.
20 |
21 | All the congestion control callback functions are collected in a C++ class CCC. You have to inherit this class to define your own congestion control algorithm. That is, UDT/CCC uses an
22 | object-oriented design. CCC in defined in ccc.h, which you have to include in your files in order to enable this feature.
23 |
24 | The CCC class contains two control variables: m_dPktSndPeriod, and m_dCWndSize. m_dPktSndPeriod is a double float number representing the packet sending period (as to be used in rate
25 | control), in microseconds. m_dCWndSize is a double float number representing the size of the congestion window (cwnd), in number of packets. The congestion control algorithm will need to
26 | update at least one of them. For example, for pure window based approach, m_dPktSndPeriod should always be zero.
27 |
28 | The fast way to learn CCC is to use the examples in ./app/cc.h. The file cc.h also includes many more advanced control mechanisms that your control classes can be derived from. For
29 | example, if you are designing a new TCP variant, you can implement the new control class directly from CTCP.
30 |
31 | Here we demonstrate the usage of UDT/CCC by writing a reliable UDP blast control mechanism.
32 |
33 |
34 | class CUDPBlast: public CCC
35 | {
36 | public:
37 | CUDPBlast() {m_dCWndSize = 83333.0;}
38 |
39 | public:
40 | void setRate(int mbps)
41 | {
42 | m_dPktSndPeriod = (m_iMSS * 8.0) / mbps;
43 | }
44 | };
45 |
46 | In this example, CUDPBlast inherits from the base class CCC. In the constructor, it sets the congestion window size to a large value so that it will not affect the packet sending. (This
47 | is pure rate based method to blast UDP packets.) The method SetRate() can be used to set a fixed packet sending rate at any time.
48 |
49 | The application can use setsockopt/getsockopt to assign this control class to a UDT instance, and/or set its parameters.
50 |
51 |
52 | UDT::setsockopt(usock, 0, UDT_CC, new CCCFactory<CUDPBlast>
53 |
54 | , sizeof(CCCFactory<CUDPBlast>
55 | ));
56 |
57 |
58 |
59 | The above code assigns the CUDPBlast control algorthm to a UDT socket usock. Note that CCCFactory is using the Abstract Factory design pattern.
60 |
61 | To set a specific data sending rate, the application needs to obtain a handle to the concrete CCC class instance used by the UDT socket usock.
62 |
63 |
64 | CUDPBlast* cchandle = NULL;
65 | int temp;
66 | UDT::getsockopt(usock, 0, UDT_CC, &cchandle, &temp);
67 |
68 |
69 | The application can then call the method of setRate() to set a 500Mbps data rate.
70 |
71 |
72 | if (NULL != cchandle)
73 | cchandle->setRate(500);
74 |
75 |
76 | The UDT/CCC can be used to implement most control mechanims, including but not limited to rate-based approaches, TCP variants (e.g., TCP, Scalable, HighSpeed, BiC, Vegas, FAST), and
77 | group-based approaches (e.g., GTP, CM).
78 |
79 | Note
80 | 1. Do NOT call regular UDT API inside CCC or its derived classes. Unknown error could happen.
81 |
82 | 2. CCCFactory<...> is a C++ template class. You do not need to derive any classes from it.
83 |
84 | 3. UDT will not release the CCCFactory<...> instance. The application should release it, at anywhere after the setsockopt() call.
85 |
86 | See Also
87 | Congestion Control Class
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/udt4/doc/doc/t-data.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Tutorial
11 |
12 | Transfering Data using UDT
13 | This section describes using UDT to transfer data in streaming mode. This is exactly the same as using traditional BSD socket.
14 |
15 | In streaming mode, neither a send or a recv call can guarantee that all data are sent or received in one call, because there is no boundary information in the data stream. Application
16 | should use loops for both sending and receiving.
17 |
18 | Example: send a data block (buf, size) using UDT.
19 |
20 | int ssize = 0;
21 | int ss;
22 | while (ssize < size)
23 | {
24 | if (UDT::ERROR == (ss = UDT::send(usock, buf + ssize, size - ssize, 0)))
25 | {
26 | cout << "send:" << UDT::getlasterror().getErrorMessage() << endl;
27 | break;
28 | }
29 |
30 | ssize += ss;
31 | }
32 |
33 |
34 | Similarily, to receive data stream, the following example code can be used.
35 | Example: receive "size" of data into buffer "buf"
36 |
37 | int rsize = 0;
38 | int rs;
39 | while (rsize < size)
40 | {
41 | if (UDT::ERROR == (rs = UDT::recv(usock, buf + rsize, size - rsize, 0)))
42 |
43 | cout << "recv:" << UDT::getlasterror().getErrorMessage() << endl;
44 | break;
45 | }
46 |
47 | rsize += rs;
48 | }
49 |
50 |
51 | Blocking vs. Non-blocking
52 | UDT supports both blocking and non-blocking mode. The above example demonstrated the blocking mode. In non-blocking mode, UDT::send and UDT::recv will return immediately if there is
53 | no buffer available. Usually, non-blocking calls are used together with accept.
54 | UDT also supports timed blocking IO with UDT_SNDTIMEO and UDT_RCVTIMEO. This is in the middle between complete blocking and complete non-blocking calls. Timed IO will block the
55 | sending or receiving call for a limited period. This is sometimes useful if the application does not know if and when the peer side will send a message.
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/udt4/doc/doc/t-error.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Tutorial
11 |
12 | Error Handling
13 | All UDT API will return an error upon a failed operation. Particularly, UDT defines UDT::INVALID_SOCK and UDT::ERROR as error returned values. Application should check the return
14 | value against these two constants (several routine return false as error value).
15 |
16 | On error, getlasterror can be used to retrieve the error information. In fact, the function returns the latest error occurred in the thread where the function is called. getlasterror returns an ERRORINFO structure, it contains both the error code and special text error message. Two helper functions of getErrorCode and getErrorMessage can be used to read these
17 | information.
18 | The UDT error information is thread local (that is, an error in another thread will not affect the error information in the current thread). The returned value is a reference to the UDT internal error structure.
19 | Note that a successful call will NOT clear the error. Therefore, applications should use the return value of a UDT API to check the result of a UDT call. getlasterror only provides detailed information when necessary. However, application can use getlasterror().clear() to clear the previously logged error if needed.
20 | Example : check UDT::bind error.
21 |
22 | sockaddr_in my_addr;
23 | my_addr.sin_family = AF_INET;
24 | my_addr.sin_port = htons(21); //invalid port number
25 | my_addr.sin_addr.s_addr = INADDR_ANY;
26 | memset(&(my_addr.sin_zero), '\0', 8);
27 |
28 | UDTSOCKET serv = UDT::socket(AF_INET, SOCK_STREAM, 0);
29 | if (UDT::ERROR == UDT::bind(serv, (sockaddr*)&my_addr, sizeof(my_addr)))
30 | {
31 | cout << "bind: " << UDT::getlasterror().getErrorMessage();
32 | // further action may depends on UDT::getlasterror().getErrorCode().
33 | // system level error can be accessed through "errno"
34 | return 0;
35 | }
36 |
37 |
38 | In the example above, the output will be:
39 |
40 | error message: Couldn't set up network connection: Permission denied.
41 |
42 |
43 | The UDT error code only reflects the operation error of the UDT socket level. Applications can still read the system level error (e.g., errno in Linux, GetLastError in Windows) to read
44 | more specific error information. However, the error message obtained by getErrorMessage contains information of both the UDT level error and the system level error.
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/udt4/doc/doc/t-file.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Tutorial
11 |
12 | File Transfer using UDT
13 | While you can always use regular UDT::send and UDT::recv to transfer a file, UDT provides a more convinient and optimized way for file transfer. An application can use UDT::sendfile
14 | and UDT::recvfile directly. In addition, file transfer IO API and regular data IO API are orthogonal. E.g., the data stream sent out by UDT::sendfile does not necessarily require
15 | UDT::recvfile to accept.
16 |
17 | The sendfile and recvfile methods are blocking call and are not affected by UDT_SNDSYN, UDT_RCVSYN, UDT_SBDTIMEO, or UDT_RCVTIMEO. They always complete the call with the specified
18 | size parameter for sending or receiving unless errors occur.
19 |
20 | UDT uses C++ fstream for file IO.
21 |
22 | Example : send a file using UDT.
23 |
24 | UDTSOCKET fhandle;
25 | ...
26 |
27 | ifstream& ifs("largefile.dat");
28 | ifs.seekg(0, ios::end);
29 | streampos size = ifs.tellg();
30 | ifs.seekg(0, ios::beg);
31 |
32 | if (UDT::ERROR == UDT::sendfile(fhandle, ifs, 0, size))
33 | {
34 | cout << "sendfile: " << UDT::getlasterror().getErrorMessage();
35 | return 0;
36 | }
37 |
38 |
39 | Example : Receive data into a file.
40 |
41 | UDTSOCKET recver;
42 | ...
43 |
44 | ofstream& ofs("largefile.dat");
45 |
46 | if (UDT::ERROR == UDT::recvfile(fhandle, ofs, 0, size))
47 | {
48 | cout << "recvfile: " << UDT::getlasterror().getErrorMessage();
49 | return 0;
50 | }
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/udt4/doc/doc/t-firewall.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Tutorial
11 |
12 | Firewall Traversing with UDT
13 | While UDT was originally written for extremely high speed data transfer, there are many other potential benefits from this reliable UDP-based library. One particular usage is to setup
14 | reliable connections between machines behind firewalls. To meet this requirement, UDT has added the rendezvous connection setup support.
15 |
16 | Traditional BSD socket setup process requires explicit server side and client side. To punch NAT firewalls, a common method is to use the SO_REUSEADDR socket option to open two sockets
17 | bound to the same port, one listens and the other connects. UDT provides the more convenient rendezvous connection setup, in which there is no server or client, and two users can connect to
18 | each other directly.
19 |
20 | With UDT, all sockets within one process can be bound to the same UDP port (but at most one listening socket on the same port is allowed). This is also helpful for system administrators to open a specific UDP port for all UDT traffic.
21 |
22 | Example: Rendezvous connection setup. (Note that there is no need to set UDT_REUSEADDR here because it is true by default.)
23 |
24 | UDTSOCKET u;
25 | ...
26 |
27 | bool rendezvous = true;
28 | UDT::setsockopt(u, 0, UDT_RENDEZVOUS, &rendezvous, sizeof(bool));
29 | UDT::bind(u, &known_addr, sizeof(known_addr));
30 | UDT::connect(u, &peer_addr, sizeof(peer_addr));
31 |
32 |
33 | In addition, UDT also allows to bind on an existing UDP socket. This is useful in two situations. First, sometimes the application must send packet to a name server in order to obtain its address (for example, this is true when behind an NAT firewall). Users may create a UDP socket and send some UDP packets to the name server to obtain the binding address. Then the UDP socket can be used directly for UDT (see bind ) so that the application does not need to close the UDP socket and open a new UDT socket on the same address again.
34 | Second, some firewalls working on local system may change the port mapping or close the "hole" is the punching UDP socket is closed, thus a new UDT socket on the same address will not be able to traverse the firewall. In this situation, binding the UDT socket on the existing UDP socket is not only convenient but necessary.
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/udt4/doc/doc/t-hello.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Tutorial
11 |
12 | Hello World!
13 | In this section we will introduce the simplest UDT program that can transfer data in high performance.
14 |
15 | This simple "Hello World!" example includes a server program and a client program just like any socket programming tutorial. These are the simpler version of the appserver and appclient
16 | examples in ./app directory.
17 |
18 | To compile, use gcc -o server server.cpp -I
19 |
20 | -L
21 |
22 | -ludt -lstdc++ -lpthread . For more details, please refer to the Makefile in ./app directory.
23 |
24 | UDT server example
25 |
26 |
27 | #include <arpa/inet.h>
28 | #include <udt.h>
29 | #include <iostream.h>
30 |
31 | using namespace std;
32 |
33 | int main()
34 | {
35 | UDTSOCKET serv = UDT::socket(AF_INET, SOCK_STREAM, 0);
36 |
37 | sockaddr_in my_addr;
38 | my_addr.sin_family = AF_INET;
39 | my_addr.sin_port = htons(9000);
40 | my_addr.sin_addr.s_addr = INADDR_ANY;
41 | memset(&(my_addr.sin_zero), '\0', 8);
42 |
43 | if (UDT::ERROR == UDT::bind(serv, (sockaddr*)&my_addr, sizeof(my_addr)))
44 | {
45 | cout << "bind: " << UDT::getlasterror().getErrorMessage();
46 | return 0;
47 | }
48 |
49 | UDT::listen(serv, 10);
50 |
51 | int namelen;
52 | sockaddr_in their_addr;
53 |
54 | UDTSOCKET recver = UDT::accept(serv, (sockaddr*)&their_addr, &namelen);
55 |
56 | char ip[16];
57 | cout << "new connection: " << inet_ntoa(their_addr.sin_addr) << ":" << ntohs(their_addr.sin_port) << endl;
58 |
59 | char data[100];
60 |
61 | if (UDT::ERROR == UDT::recv(recver, data, 100, 0))
62 | {
63 | cout << "recv:" << UDT::getlasterror().getErrorMessage() << endl;
64 | return 0;
65 | }
66 |
67 | cout << data << endl;
68 |
69 | UDT::close(recver);
70 | UDT::close(serv);
71 |
72 | return 1;
73 | }
74 |
75 |
76 | This simple server tries to bind itself at port 9000. If succeed, it listens at port 9000 and accepts a client and then reads a string.
77 | UDT client example
78 |
79 | #include <iostream>
80 | #include <udt.h>
81 | #include <arpa/inet.h>
82 |
83 | using namespace std;
84 | using namespace UDT;
85 |
86 | int main()
87 | {
88 | UDTSOCKET client = UDT::socket(AF_INET, SOCK_STREAM, 0);
89 |
90 | sockaddr_in serv_addr;
91 | serv_addr.sin_family = AF_INET;
92 | serv_addr.sin_port = htons(9000);
93 | inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
94 |
95 | memset(&(serv_addr.sin_zero), '\0', 8);
96 |
97 | // connect to the server, implict bind
98 | if (UDT::ERROR == UDT::connect(client, (sockaddr*)&serv_addr, sizeof(serv_addr)))
99 | {
100 | cout << "connect: " << UDT::getlasterror().getErrorMessage();
101 | return 0;
102 | }
103 |
104 | char* hello = "hello world!\n";
105 | if (UDT::ERROR == UDT::send(client, hello, strlen(hello) + 1, 0))
106 | {
107 | cout << "send: " << UDT::getlasterror().getErrorMessage();
108 | return 0;
109 | }
110 |
111 | UDT::close(client);
112 |
113 | return 1;
114 | }
115 |
116 |
117 | The client side connects to the local address (127.0.0.1) at port 9000, and sends a "hello world!" message.
118 | Note that in this "Hello World!" example the UDT::send and UDT::recv routines should use a loop to check return value. However, since the string length is very small and can be hold in one packet, we omit the loop part in order to give a simpler example.
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/udt4/doc/doc/t-intro.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Tutorial
11 |
12 | Introduction to Programming with UDT
13 | The prerequisite knowledge for using UDT is sound experience on C++ and socket programing. This is enough to use UDT in distributed applications. If you are familiar with computer
14 | networking, you may find UDT more powerful.
15 |
16 | UDT is a C++ library, which has almost identical routines as the BSD socket APIs. Using UDT in a C++ program is very straightforward. In fact, you may easily modify your existing code
17 | from TCP to UDT.
18 |
19 | Because of the similarity between UDT API and BSD socket API, UDT defines its own namespace UDT to differentiate the UDT APIs from the regular socket APIs. A qualifier of UDT:: should be
20 | put before the UDT socket call. UDTSOCKET is a data type to describe a UDT socket. For a complete UDT structures and constant definitions, please see Reference:UDT Structures. For a complete
21 | description of UDT socket APIs, please see Reference:UDT Functions.
22 |
23 | For those socket APIs that does not involve with a socket descriptor, e.g., inet_pton, they are not wrapped by UDT API, and the applications should continue to use the original functions.
24 | For those socket APIs or options not appropriate to UDT, e.g., certain TCP options, they are simply not available in UDT API.
25 |
26 | For example, using BSD socket, you write:
27 |
28 |
29 | int s = socket(AF_INET, SOCK_STREAM, 0);
30 |
31 |
32 | Its counterpart in UDT is like this:
33 |
34 |
35 | UDTSOCKET u = UDT::socket(AF_INET, SOCK_STREAM, 0);
36 |
37 |
38 | UDT API is thread-safe. UDT sockets can be shared by multiple threads and UDT API on the same socket can be made concurrently. However, because of its application level nature, UDT
39 | sockets cannot be shared among processes. That is, a UDT socket created in one process cannot be used in another process.
40 |
41 | If you use a programming language other than C++, you may need to write certain wrapper for the UDT C++ API. For example, you may use "extern C" to wrap UDT API in C; there are also
42 | ways to call C++ API in Java.
43 |
44 | To use UDT in a C++ application:
45 |
46 | Header
47 | #include <udt.h>
48 |
49 | Library (depending on platforms)
50 | libudt.so libudt.a udt.dll udt.lib udt.dylib
51 |
52 | Namespace
53 | UDT
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/udt4/doc/doc/t-msg.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Tutorial
11 |
12 | Messaging with Partial Reliability
13 | When a UDT socket is created as SOCK_DGRAM type, UDT will send and receive data as messages. The boundary of the message is preserved and the message is delivered
14 | as a whole unit. Sending or receving messages do not need a loop; a message will be either completely delivered or not delivered at all. However, at the receiver
15 | side, if the user buffer is shorter than the message length, only part of the message will be copied into the user buffer while the message will still be
16 | discarded.
17 |
18 | Example: send and receive messages using UDT.
19 |
20 | UDTSOCKET u = UDT::socket(AF_INET, SOCK_DGRAM, 0);
21 |
22 | char data[1024];
23 | int size = 1024;
24 |
25 | int ssize = UDT::sendmsg(client, data, size, -1, false);
26 |
27 | int rsize = UDT::recvmsg(u, data, size);
28 |
29 |
30 | At the sender side, applications can specify two options for every message. The first is the life time (TTL) of a message. The default value is infinite, which
31 | means that the message will always be delivered. If the value is a postive one, UDT will discard the message if it cannot be delivered by the life time expires.
32 | The second is the order of the message. An in-order message means that this message will not be delivered unless all the messages prior to it are either delivered
33 | or discarded.
34 |
35 | Synchronization modes (blocking vs. non-blocking) are also applied to SOCK_DGRAM sockets, so does not other UDT mechanisms including but limited to congestion
36 | control, flow control, and connection maintainence. Finally, note that UDT SOCK_DGRAM socket is also connection oriented. A UDT connection can only be set up
37 | between the same socket types.
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/udt4/doc/doc/t-udt3.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Tutorial
11 |
12 | Transition from UDT3
13 | If you have never used UDT before, please skip this page.
14 |
15 | If you are familiar with previous versions of UDT, in particular UDT3, please noted that we have several major changes in UDT4 and you may need to modify your existing code a little
16 | in order to use UDT4. In addition, different versions of UDT do not communicate with each other.
17 |
18 | UDT4 have made the following improvements
19 |
20 | UDT4 uses a UDP multiplexer for multiple UDT sockets, therefore it is possible (and by default) all UDT sockets in one process will share one UDP port. This scheme makes it easier
21 | for firewall traversing.
22 | UDT4 has a new buffer management module that enables all UDT sockets in one process can share protocol buffer. The goodness it brings is the much less memory usage for multiple
23 | UDT connections compared to previous versions.
24 | UDT4 can automatically resize its buffer in order to reduce memory usage while providing maximum throughput.
25 | Because of the new memory management scheme, overlapped IO has been removed from UDT4. If your existing code uses overlapped IO, you need to modify it to use regular IO. This is
26 | the only change needed for exiting code to move from UDT3 to UDT4.
27 | UDT4 has an enhanced code based and some bug fixes.
28 |
29 |
30 | Finally, UDT4 does not provide the NS-2 simulation code (nor any support to previous versions of simulation code) any more.
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/udt4/doc/doc/trace.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UDT Reference
6 |
7 |
8 |
9 |
10 | UDT Reference: Functions
11 |
12 | perfmon
13 | The perfmon method retrieves the internal protocol parameters and performance trace.
14 |
15 | int perfmon(
16 | UDTSOCKET u ,
17 | TRACEINFO* perf ,
18 | bool clear = true
19 | );
20 |
21 | Parameters
22 |
23 | u
24 | [in] Descriptor identifying a UDT entity.
25 | trace
26 | [out] Pointer to the TRACEINFO structure to store the performance information.
27 | clear
28 | [in] Flag that indicates if the local traces should be cleared and counts should be restarted.
29 |
30 |
31 | Return Value
32 | If success, 0 is returned and trace information is written into trace ; otherwise, UDT::ERROR is returned and specific error information can be retrieved by getlasterror .
34 |
35 |
36 |
37 | Error Name
38 | Error Code
39 | Comment
40 |
41 |
42 | ECONNLOST
43 | 2001
44 | connection is broken.
45 |
46 |
47 | EINVSOCK
48 | 5004
49 | u is an invalid socket.
50 |
51 |
52 | EUNBOUNDSOCK
53 | 5005
54 | u is not connected.
55 |
56 |
57 |
58 | Description
59 | The perfmon method reads the performance data since the last time perfmon is executed, or since the connection is started. The result in written into a TRACEINFO structure.
60 | There are three kinds of performance information that can be read by applications: the total counts since the connection is started, the periodical counts since last time the counts are cleared, and instant parameter values.
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/udt4/doc/doc/treeview.css:
--------------------------------------------------------------------------------
1 | /* jSh - Stylesheet for JavaScript TreeView documentation */
2 |
3 | pre { margin-left:10px; }
4 | h1,h2,h3,h4,h5,h6,pre,tt { color:#0000CC; }
5 | a.an { text-decoration:none; }
6 | a:active { color:#CC0000; text-decoration:none; }
7 | a:link { color:#CC0000; text-decoration:underline; }
8 | a:visited { color:#990066; text-decoration:underline; }
9 |
--------------------------------------------------------------------------------
/udt4/doc/doc/tutorial.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Introduction
6 |
7 |
8 |
9 |
10 | UDT Tutorial
11 | This tutorial is a quick guide on how to program with UDT and includes explanations and examples. You can learn the basics of UDT programming in this tutorial. This tutorial supposes that
12 | you are familiar with socket programming. The example codes can be found in the ./app directory of the software release, which can be compiled and run directly.
13 |
14 | In this section:
15 |
16 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/udt4/doc/doc/udtdoc.css:
--------------------------------------------------------------------------------
1 | /* CSS Document */
2 |
3 | body {
4 | background-color: #FFFFFF;
5 | font-family: Verdana, Arial, Helvetica, sans-serif;
6 | font-size: 12px;
7 | line-height: 18px;
8 | color: #333333;
9 | }
10 |
11 | .note1 {
12 | font-family: Verdana, Arial, Helvetica, sans-serif;
13 | font-size: 12px;
14 | font-style: normal;
15 | line-height: normal;
16 | color: #333333;
17 | padding: 0px 0px 10px 10px;
18 | margin-top: 0;
19 | margin-bottom: 0;
20 | list-style-image: none;
21 | }
22 |
23 | .ref_head {
24 | font-family: Verdana, Arial, Helvetica, sans-serif;
25 | font-size: 12px;
26 | font-style: italic;
27 | font-weight: bold;
28 | background-color: #99CCFF;
29 | padding: 3px 3px 3px 3px;
30 | }
31 |
32 | .code {
33 | font-family: "Courier New", Courier, monospace;
34 | font-size: 10px;
35 | line-height: 12px;
36 | background-color: #C0C0C0;
37 | padding: 5px 5px 5px 5px;
38 | }
39 |
40 | .func_name {
41 | font-family: Verdana, Arial, Helvetica, sans-serif;
42 | font-size: 18px;
43 | color: #000000;
44 | }
45 |
46 | .table_headline {
47 | font-family: Verdana, Arial, Helvetica, sans-serif;
48 | font-size: 12px;
49 | background-color: #C0C0C0;
50 | padding: 2px 2px 2px 2px;
51 | }
52 |
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_book.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_book.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_down.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_down.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_end.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_end.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_endm.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_endm.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_endp.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_endp.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_leaf.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_leaf.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_line.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_line.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_link.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_link.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_list.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_list.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_listm.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_listm.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_listp.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_listp.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_open.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_open.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_space.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_space.gif
--------------------------------------------------------------------------------
/udt4/doc/hlp/ix_up.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/hlp/ix_up.gif
--------------------------------------------------------------------------------
/udt4/doc/index.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | UDT Manual
5 |
6 |
7 |
8 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | This page uses frames, but your browser doesn't support them.
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/udt4/doc/main.htm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/libinzhangyuan/udt_patch_for_epoll/d65aa2d5841315590b0b266512d47cb61cf46c38/udt4/doc/main.htm
--------------------------------------------------------------------------------
/udt4/src/Makefile:
--------------------------------------------------------------------------------
1 | C++ = g++ -g
2 |
3 | ifndef os
4 | os = LINUX
5 | endif
6 |
7 | ifndef arch
8 | arch = IA32
9 | endif
10 |
11 | CCFLAGS = -fPIC -Wall -Wextra -D$(os) -finline-functions -O3 -fno-strict-aliasing #-msse3
12 |
13 | ifeq ($(arch), IA32)
14 | CCFLAGS += -DIA32
15 | endif
16 |
17 | ifeq ($(arch), POWERPC)
18 | CCFLAGS += -mcpu=powerpc
19 | endif
20 |
21 | ifeq ($(arch), SPARC)
22 | CCFLAGS += -DSPARC
23 | endif
24 |
25 | ifeq ($(arch), IA64)
26 | CCFLAGS += -DIA64
27 | endif
28 |
29 | ifeq ($(arch), AMD64)
30 | CCFLAGS += -DAMD64
31 | endif
32 |
33 | OBJS = md5.o common.o window.o list.o buffer.o packet.o channel.o queue.o ccc.o cache.o core.o epoll.o api.o
34 | DIR = $(shell pwd)
35 |
36 | all: libudt.so libudt.a udt
37 |
38 | %.o: %.cpp %.h udt.h
39 | $(C++) $(CCFLAGS) $< -c
40 |
41 | libudt.so: $(OBJS)
42 | ifneq ($(os), OSX)
43 | $(C++) -shared -o $@ $^
44 | else
45 | $(C++) -dynamiclib -o libudt.dylib -lstdc++ -lpthread -lm $^
46 | endif
47 |
48 | libudt.a: $(OBJS)
49 | ar -rcs $@ $^
50 |
51 | udt:
52 | cp udt.h udt
53 |
54 | clean:
55 | rm -f *.o *.so *.dylib *.a udt
56 |
57 | install:
58 | export LD_LIBRARY_PATH=$(DIR):$$LD_LIBRARY_PATH
59 |
--------------------------------------------------------------------------------
/udt4/src/cache.cpp:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | Copyright (c) 2001 - 2009, The Board of Trustees of the University of Illinois.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are
7 | met:
8 |
9 | * Redistributions of source code must retain the above
10 | copyright notice, this list of conditions and the
11 | following disclaimer.
12 |
13 | * Redistributions in binary form must reproduce the
14 | above copyright notice, this list of conditions
15 | and the following disclaimer in the documentation
16 | and/or other materials provided with the distribution.
17 |
18 | * Neither the name of the University of Illinois
19 | nor the names of its contributors may be used to
20 | endorse or promote products derived from this
21 | software without specific prior written permission.
22 |
23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | *****************************************************************************/
35 |
36 | /*****************************************************************************
37 | written by
38 | Yunhong Gu, last updated 05/05/2009
39 | *****************************************************************************/
40 |
41 | #ifdef WIN32
42 | #include
43 | #include
44 | #ifdef LEGACY_WIN32
45 | #include
46 | #endif
47 | #endif
48 |
49 | #include
50 | #include "cache.h"
51 | #include "core.h"
52 |
53 | using namespace std;
54 |
55 | CInfoBlock& CInfoBlock::operator=(const CInfoBlock& obj)
56 | {
57 | std::copy(obj.m_piIP, obj.m_piIP + 3, m_piIP);
58 | m_iIPversion = obj.m_iIPversion;
59 | m_ullTimeStamp = obj.m_ullTimeStamp;
60 | m_iRTT = obj.m_iRTT;
61 | m_iBandwidth = obj.m_iBandwidth;
62 | m_iLossRate = obj.m_iLossRate;
63 | m_iReorderDistance = obj.m_iReorderDistance;
64 | m_dInterval = obj.m_dInterval;
65 | m_dCWnd = obj.m_dCWnd;
66 |
67 | return *this;
68 | }
69 |
70 | bool CInfoBlock::operator==(const CInfoBlock& obj)
71 | {
72 | if (m_iIPversion != obj.m_iIPversion)
73 | return false;
74 |
75 | else if (m_iIPversion == AF_INET)
76 | return (m_piIP[0] == obj.m_piIP[0]);
77 |
78 | for (int i = 0; i < 4; ++ i)
79 | {
80 | if (m_piIP[i] != obj.m_piIP[i])
81 | return false;
82 | }
83 |
84 | return true;
85 | }
86 |
87 | CInfoBlock* CInfoBlock::clone()
88 | {
89 | CInfoBlock* obj = new CInfoBlock;
90 |
91 | std::copy(m_piIP, m_piIP + 3, obj->m_piIP);
92 | obj->m_iIPversion = m_iIPversion;
93 | obj->m_ullTimeStamp = m_ullTimeStamp;
94 | obj->m_iRTT = m_iRTT;
95 | obj->m_iBandwidth = m_iBandwidth;
96 | obj->m_iLossRate = m_iLossRate;
97 | obj->m_iReorderDistance = m_iReorderDistance;
98 | obj->m_dInterval = m_dInterval;
99 | obj->m_dCWnd = m_dCWnd;
100 |
101 | return obj;
102 | }
103 |
104 | int CInfoBlock::getKey()
105 | {
106 | if (m_iIPversion == AF_INET)
107 | return m_piIP[0];
108 |
109 | return m_piIP[0] + m_piIP[1] + m_piIP[2] + m_piIP[3];
110 | }
111 |
112 | void CInfoBlock::convert(const sockaddr* addr, const int& ver, uint32_t ip[])
113 | {
114 | if (ver == AF_INET)
115 | {
116 | ip[0] = ((sockaddr_in*)addr)->sin_addr.s_addr;
117 | ip[1] = ip[2] = ip[3] = 0;
118 | }
119 | else
120 | {
121 | memcpy((char*)ip, (char*)((sockaddr_in6*)addr)->sin6_addr.s6_addr, 16);
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/udt4/src/md5.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
3 |
4 | This software is provided 'as-is', without any express or implied
5 | warranty. In no event will the authors be held liable for any damages
6 | arising from the use of this software.
7 |
8 | Permission is granted to anyone to use this software for any purpose,
9 | including commercial applications, and to alter it and redistribute it
10 | freely, subject to the following restrictions:
11 |
12 | 1. The origin of this software must not be misrepresented; you must not
13 | claim that you wrote the original software. If you use this software
14 | in a product, an acknowledgment in the product documentation would be
15 | appreciated but is not required.
16 | 2. Altered source versions must be plainly marked as such, and must not be
17 | misrepresented as being the original software.
18 | 3. This notice may not be removed or altered from any source distribution.
19 |
20 | L. Peter Deutsch
21 | ghost@aladdin.com
22 |
23 | */
24 | /* $Id: md5.h,v 1.2 2007/12/24 05:58:37 lilyco Exp $ */
25 | /*
26 | Independent implementation of MD5 (RFC 1321).
27 |
28 | This code implements the MD5 Algorithm defined in RFC 1321, whose
29 | text is available at
30 | http://www.ietf.org/rfc/rfc1321.txt
31 | The code is derived from the text of the RFC, including the test suite
32 | (section A.5) but excluding the rest of Appendix A. It does not include
33 | any code or documentation that is identified in the RFC as being
34 | copyrighted.
35 |
36 | The original and principal author of md5.h is L. Peter Deutsch
37 | . Other authors are noted in the change history
38 | that follows (in reverse chronological order):
39 |
40 | 2002-04-13 lpd Removed support for non-ANSI compilers; removed
41 | references to Ghostscript; clarified derivation from RFC 1321;
42 | now handles byte order either statically or dynamically.
43 | 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
44 | 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
45 | added conditionalization for C++ compilation from Martin
46 | Purschke .
47 | 1999-05-03 lpd Original version.
48 | */
49 |
50 | #ifndef md5_INCLUDED
51 | # define md5_INCLUDED
52 |
53 | /*
54 | * This package supports both compile-time and run-time determination of CPU
55 | * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
56 | * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
57 | * defined as non-zero, the code will be compiled to run only on big-endian
58 | * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
59 | * run on either big- or little-endian CPUs, but will run slightly less
60 | * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
61 | */
62 |
63 | typedef unsigned char md5_byte_t; /* 8-bit byte */
64 | typedef unsigned int md5_word_t; /* 32-bit word */
65 |
66 | /* Define the state of the MD5 Algorithm. */
67 | typedef struct md5_state_s {
68 | md5_word_t count[2]; /* message length in bits, lsw first */
69 | md5_word_t abcd[4]; /* digest buffer */
70 | md5_byte_t buf[64]; /* accumulate block */
71 | } md5_state_t;
72 |
73 | #ifdef __cplusplus
74 | extern "C"
75 | {
76 | #endif
77 |
78 | /* Initialize the algorithm. */
79 | void md5_init(md5_state_t *pms);
80 |
81 | /* Append a string to the message. */
82 | void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
83 |
84 | /* Finish the message and return the digest. */
85 | void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
86 |
87 | #ifdef __cplusplus
88 | } /* end extern "C" */
89 | #endif
90 |
91 | #endif /* md5_INCLUDED */
92 |
--------------------------------------------------------------------------------
/udt4/ssl/Makefile:
--------------------------------------------------------------------------------
1 | LFLAGS = -I../src -L../src -lssl -lcrypto -ludt -lstdc++ -lpthread
2 | CC = g++
3 |
4 | all: tls_client tls_server
5 |
6 | tls_common.o: tls_common.cpp tls_common.h e_os.h
7 | $(CC) tls_common.cpp -c $(LFLAGS)
8 |
9 | tls: tls_client tls_server
10 |
11 | tls_client: tls_common.o tls_client.cpp
12 | $(CC) $^ -o $@ $(LFLAGS)
13 |
14 | tls_server: tls_common.o tls_server.cpp
15 | $(CC) $^ -o $@ $(LFLAGS)
16 |
17 |
--------------------------------------------------------------------------------
/udt4/ssl/epoll.cpp:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | Copyright 2013 Laboratory for Advanced Computing at the University of Chicago
3 |
4 | This file is part of .
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions
16 | and limitations under the License.
17 | *****************************************************************************/
18 |
19 | struct udt_epoll_args {
20 | int efd;
21 | int signal_fd;
22 | };
23 |
24 |
25 | void *epoll_signal_thread(void *my_args)
26 | {
27 | struct udt_epoll_args *args = (struct udt_epoll_args*)my_args;
28 | std::set udt_read_fds;
29 | char sink[1];
30 | int ret;
31 |
32 | while (true) {
33 | ret = UDT::epoll_wait(args->efd, &udt_read_fds, NULL, -1);
34 | if (ret < 1 || udt_read_fds.size() < 1)
35 | break;
36 | write(args->signal_fd, "", 1);
37 | }
38 | }
39 |
40 |
41 | int udt_epoll(int udt_efd, pthread_t *signal_thread)
42 | {
43 | int proxy_fd[2];
44 | struct udt_epoll_args *args;
45 |
46 | args = (struct udt_epoll_args*)malloc(sizeof(struct udt_epoll_args));
47 |
48 | pipe(proxy_fd);
49 |
50 | args->signal_fd = proxy_fd[1];
51 | args->efd = udt_efd;
52 |
53 | pthread_create(signal_thread, NULL, epoll_signal_thread, (void*)args);
54 |
55 | fcntl(proxy_fd[0], F_SETFL, O_NONBLOCK);
56 |
57 | return proxy_fd[0];
58 | }
59 |
60 | int udt_epoll_wait(int udt_efd, int signal_sink, set* udt_read_fds)
61 | {
62 | UDT::epoll_wait(udt_efd, &udt_read_fds, NULL, -1, &read_fds);
63 | read(signal_sink, sink, 1);
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/udt4/ssl/tls_common.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | Copyright 2013 Laboratory for Advanced Computing at the University of Chicago
3 |
4 | This file is part of .
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions
16 | and limitations under the License.
17 | *****************************************************************************/
18 |
19 | #ifndef TLS_COMMON_H
20 | #define TLS_COMMON_H
21 |
22 | #include
23 |
24 | #include
25 |
26 | static BIO *bio_err = NULL;
27 | static const char rnd_seed[] = "string to make the random number generator think it has entropy";
28 |
29 | int doit_biopair(SSL *s_ssl, UDTSOCKET recver, int is_server, int in_file, int out_file);
30 |
31 | int ctx_init(SSL_CTX **ctx);
32 |
33 | int verify_paths(SSL_CTX *ctx);
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/udt4/tuner/Makefile:
--------------------------------------------------------------------------------
1 | C++ = g++
2 |
3 | ifndef os
4 | os = LINUX
5 | endif
6 |
7 | ifndef arch
8 | arch = IA32
9 | endif
10 |
11 | CCFLAGS = -Wall -D$(os) -I../src -finline-functions -O3
12 |
13 | ifeq ($(arch), IA32)
14 | CCFLAGS += -DIA32 #-mcpu=pentiumpro -march=pentiumpro -mmmx -msse
15 | endif
16 |
17 | ifeq ($(arch), POWERPC)
18 | CCFLAGS += -mcpu=powerpc
19 | endif
20 |
21 | ifeq ($(arch), IA64)
22 | CCFLAGS += -DIA64
23 | endif
24 |
25 | ifeq ($(arch), SPARC)
26 | CCFLAGS += -DSPARC
27 | endif
28 |
29 | LDFLAGS = -L../src -ludt -lstdc++ -lpthread -lm
30 |
31 | ifeq ($(os), UNIX)
32 | LDFLAGS += -lsocket
33 | endif
34 |
35 | ifeq ($(os), SUNOS)
36 | LDFLAGS += -lrt -lsocket
37 | endif
38 |
39 | DIR = $(shell pwd)
40 |
41 | APP = appserver appclient sendfile recvfile
42 |
43 | all: $(APP)
44 |
45 | %.o: %.cpp
46 | $(C++) $(CCFLAGS) $< -c
47 |
48 | appserver: appserver.o
49 | $(C++) $^ -o $@ $(LDFLAGS)
50 | appclient: appclient.o
51 | $(C++) $^ -o $@ $(LDFLAGS)
52 | sendfile: sendfile.o
53 | $(C++) $^ -o $@ $(LDFLAGS)
54 | recvfile: recvfile.o
55 | $(C++) $^ -o $@ $(LDFLAGS)
56 |
57 | clean:
58 | rm -f *.o $(APP)
59 |
60 | install:
61 | export PATH=$(DIR):$$PATH
62 |
--------------------------------------------------------------------------------
/udt4/tuner/README.md:
--------------------------------------------------------------------------------
1 | UDT Tuner
2 | ===
3 |
4 | This is a modification of udt/app/app(client/server) that takes cli args
5 | along with a bash script that will run the client server pair with UDT and
6 | sysctl settings.
7 |
8 | USAGE
9 | ------
10 | Running the bash script tune.sh will read settings from the file settings.txt then as specified by cli args ssh to a remote host load a sysctl file and start the appserver with parameters from the local settings.txt. Then tune.sh loads a local sysctl file and starts the appclient. Both the server and client run for 1 minute and are then killed. The output of appclient is writting to raw_out_testN where N is the line of settings.txt being run starting from 0.
11 |
12 | ### Basic usage:
13 | ./tune.sh 127.0.0.1 lacadmin /home/lacadmin/udr_crypto/udt/tuner/appserver /home/lacadmin/udr_crypto/udt/src
14 |
15 | tune.sh will ssh to 127.0.0.1 as lacadmin then export LD_LIBRARY_PATH=/home/lacadmin/udr_crypto/udt/src then start /home/lacadmin/udr_crypto/udt/tuner/appserver
16 |
17 | ### Example settings.txt:
18 | /etc/sysctl.conf,/etc/sysctl.conf,0 134217728 2097152 8900,0 134217728 2097152 8900 0
19 | /etc/sysctl.conf,/etc/sysctl.conf,1 134217728 2097152 8900,1 134217728 2097152 8900 10000
20 |
21 | On the remote server run:
22 | sudo sysctl -p /etc/sysctl.conf
23 | Then locally run:
24 | sudo sysctl -p /etc/sysctl.conf
25 | Then remotely run:
26 | PATH_FROM_ARGS/appserver 9000 0 134217728 2097152 8900
27 | Then locally:
28 | ./appclient HOST_FROM_ARGS 9000 0 134217728 2097152 8900 0
29 |
30 | 0 means no blast congestion control. 134217728 is the UDT buffer size, 2097152 is the UDP buffer size, 8900 is the UDT MSS, and 0 is the blast rate.
31 |
--------------------------------------------------------------------------------
/udt4/tuner/cc.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class CTCP: public CCC
5 | {
6 | public:
7 | void init()
8 | {
9 | m_bSlowStart = true;
10 | m_issthresh = 83333;
11 |
12 | m_dPktSndPeriod = 0.0;
13 | m_dCWndSize = 2.0;
14 |
15 | setACKInterval(2);
16 | setRTO(1000000);
17 | }
18 |
19 | virtual void onACK(const int& ack)
20 | {
21 | if (ack == m_iLastACK)
22 | {
23 | if (3 == ++ m_iDupACKCount)
24 | DupACKAction();
25 | else if (m_iDupACKCount > 3)
26 | m_dCWndSize += 1.0;
27 | else
28 | ACKAction();
29 | }
30 | else
31 | {
32 | if (m_iDupACKCount >= 3)
33 | m_dCWndSize = m_issthresh;
34 |
35 | m_iLastACK = ack;
36 | m_iDupACKCount = 1;
37 |
38 | ACKAction();
39 | }
40 | }
41 |
42 | virtual void onTimeout()
43 | {
44 | m_issthresh = getPerfInfo()->pktFlightSize / 2;
45 | if (m_issthresh < 2)
46 | m_issthresh = 2;
47 |
48 | m_bSlowStart = true;
49 | m_dCWndSize = 2.0;
50 | }
51 |
52 | protected:
53 | virtual void ACKAction()
54 | {
55 | if (m_bSlowStart)
56 | {
57 | m_dCWndSize += 1.0;
58 |
59 | if (m_dCWndSize >= m_issthresh)
60 | m_bSlowStart = false;
61 | }
62 | else
63 | m_dCWndSize += 1.0/m_dCWndSize;
64 | }
65 |
66 | virtual void DupACKAction()
67 | {
68 | m_bSlowStart = false;
69 |
70 | m_issthresh = getPerfInfo()->pktFlightSize / 2;
71 | if (m_issthresh < 2)
72 | m_issthresh = 2;
73 |
74 | m_dCWndSize = m_issthresh + 3;
75 | }
76 |
77 | protected:
78 | int m_issthresh;
79 | bool m_bSlowStart;
80 |
81 | int m_iDupACKCount;
82 | int m_iLastACK;
83 | };
84 |
85 |
86 | class CUDPBlast: public CCC
87 | {
88 | public:
89 | CUDPBlast()
90 | {
91 | m_dPktSndPeriod = 1000000;
92 | m_dCWndSize = 83333.0;
93 | }
94 |
95 | public:
96 | void setRate(double mbps)
97 | {
98 | m_dPktSndPeriod = (m_iMSS * 8.0) / mbps;
99 | }
100 | };
101 |
--------------------------------------------------------------------------------
/udt4/tuner/recvfile.cpp:
--------------------------------------------------------------------------------
1 | #ifndef WIN32
2 | #include
3 | #include
4 | #else
5 | #include
6 | #include
7 | #endif
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include "cc.h"
14 |
15 | using namespace std;
16 |
17 | int main(int argc, char* argv[])
18 | {
19 | if (argc != 9) {
20 | cout << "usage: recvfile server_ip server_port remote_filename local_filename use_blast(0 or 1) udt_sendbuff udp_sendbuff mss" << endl;
21 | return 1;
22 | }
23 |
24 | // use this function to initialize the UDT library
25 | UDT::startup();
26 |
27 | struct addrinfo hints, *peer;
28 |
29 | memset(&hints, 0, sizeof(struct addrinfo));
30 | hints.ai_flags = AI_PASSIVE;
31 | hints.ai_family = AF_INET;
32 | hints.ai_socktype = SOCK_STREAM;
33 |
34 | UDTSOCKET fhandle = UDT::socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol);
35 |
36 | int blast = atoi(argv[5]);
37 | int udt_recvbuff = atoi(argv[6]);
38 | int udp_recvbuff = atoi(argv[7]);
39 | int mss = atoi(argv[8]);
40 | //buffer_size = udt_recvbuff;
41 |
42 |
43 | // UDT Options
44 | if (blast)
45 | UDT::setsockopt(fhandle, 0, UDT_CC, new CCCFactory, sizeof(CCCFactory));
46 |
47 | UDT::setsockopt(fhandle, 0, UDT_MSS, &mss, sizeof(int));
48 | UDT::setsockopt(fhandle, 0, UDT_RCVBUF, &udt_recvbuff, sizeof(int));
49 | UDT::setsockopt(fhandle, 0, UDP_RCVBUF, &udp_recvbuff, sizeof(int));
50 | UDT::setsockopt(fhandle, 0, UDT_SNDBUF, &udt_recvbuff, sizeof(int));
51 | UDT::setsockopt(fhandle, 0, UDP_SNDBUF, &udp_recvbuff, sizeof(int));
52 |
53 |
54 | if (0 != getaddrinfo(argv[1], argv[2], &hints, &peer))
55 | {
56 | cout << "incorrect server/peer address. " << argv[1] << ":" << argv[2] << endl;
57 | return -1;
58 | }
59 |
60 | // connect to the server, implict bind
61 | if (UDT::ERROR == UDT::connect(fhandle, peer->ai_addr, peer->ai_addrlen))
62 | {
63 | cout << "connect: " << UDT::getlasterror().getErrorMessage() << endl;
64 | return -1;
65 | }
66 |
67 | freeaddrinfo(peer);
68 |
69 |
70 | // send name information of the requested file
71 | int len = strlen(argv[3]);
72 |
73 | if (UDT::ERROR == UDT::send(fhandle, (char*)&len, sizeof(int), 0))
74 | {
75 | cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;
76 | return -1;
77 | }
78 |
79 | if (UDT::ERROR == UDT::send(fhandle, argv[3], len, 0))
80 | {
81 | cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;
82 | return -1;
83 | }
84 |
85 | // get size information
86 | int64_t size;
87 |
88 | if (UDT::ERROR == UDT::recv(fhandle, (char*)&size, sizeof(int64_t), 0))
89 | {
90 | cout << "send: " << UDT::getlasterror().getErrorMessage() << endl;
91 | return -1;
92 | }
93 |
94 | if (size < 0)
95 | {
96 | cout << "no such file " << argv[3] << " on the server\n";
97 | return -1;
98 | }
99 |
100 | // receive the file
101 | fstream ofs(argv[4], ios::out | ios::binary | ios::trunc);
102 | int64_t recvsize;
103 | int64_t offset = 0;
104 |
105 | if (UDT::ERROR == (recvsize = UDT::recvfile(fhandle, ofs, offset, size)))
106 | {
107 | cout << "recvfile: " << UDT::getlasterror().getErrorMessage() << endl;
108 | return -1;
109 | }
110 |
111 | UDT::close(fhandle);
112 |
113 | ofs.close();
114 |
115 | // use this function to release the UDT library
116 | UDT::cleanup();
117 |
118 | return 0;
119 | }
120 |
--------------------------------------------------------------------------------
/udt4/tuner/settings.txt:
--------------------------------------------------------------------------------
1 | /etc/sysctl.conf,/etc/sysctl.conf,0 134217728 2097152 8900,0 134217728 2097152 8900 0
2 | /etc/sysctl.conf,/etc/sysctl.conf,1 134217728 2097152 8900,1 134217728 2097152 8900 10000
3 |
--------------------------------------------------------------------------------
/udt4/tuner/tune.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # example:
3 | # ./tune.sh 127.0.0.1 lacadmin /home/lacadmin/udr_crypto/udt/tuner/appserver /home/lacadmin/udr_crypto/udt/src
4 |
5 | port=9000
6 |
7 | host=$1
8 | remote_user=$2
9 | server_command=$3
10 | remote_udt_path=$4
11 |
12 | count=0
13 | interval=60
14 |
15 | settings_file=settings.txt
16 | client=./appclient
17 | export_ld="export LD_LIBRARY_PATH=$remote_udt_path"
18 |
19 | while read line; do
20 |
21 | server_sysctl=$(echo $line|cut -f1 -d ,)
22 | client_sysctl=$(echo $line|cut -f2 -d ,)
23 | server_args=$(echo $line|cut -f3 -d ,)
24 | client_args=$(echo $line|cut -f4 -d ,)
25 |
26 | sudo sysctl -p $client_sysctl
27 | ssh $remote_user@$host "sudo sysctl -p $server_sysctl" <&-
28 |
29 | ssh $remote_user@$host "$export_ld; $server_command $port $server_args & pid=\$!;sleep $interval;kill \$pid" <&- &
30 |
31 | $client $host $port $client_args > raw_out_test$count &
32 | client_pid=$!
33 |
34 | sleep $interval
35 | kill $client_pid
36 |
37 | count=$((count+1))
38 | done < $settings_file
39 |
--------------------------------------------------------------------------------
/udt4/win/recvfile.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
10 |
11 |
12 |
17 |
33 |
35 |
46 |
48 |
50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 |
67 |
72 |
86 |
88 |
98 |
100 |
102 |
104 |
106 |
108 |
110 |
112 |
114 |
116 |
118 |
119 |
120 |
121 |
122 |
123 |
126 |
128 |
129 |
130 |
133 |
135 |
136 |
137 |
140 |
141 |
143 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/udt4/win/sendfile.vcproj:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
10 |
11 |
12 |
17 |
33 |
35 |
46 |
48 |
50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 |
67 |
72 |
87 |
89 |
99 |
101 |
103 |
105 |
107 |
109 |
111 |
113 |
115 |
117 |
119 |
120 |
121 |
122 |
123 |
124 |
127 |
129 |
130 |
131 |
134 |
136 |
137 |
138 |
141 |
142 |
144 |
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/udt4/win/udt.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 8.00
2 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "appclient", "appclient.vcproj", "{4C848417-B545-468B-AA0C-44EE73BC7B9B}"
3 | ProjectSection(ProjectDependencies) = postProject
4 | {D84D100A-7C21-4CCB-B16E-0FB37137C16C} = {D84D100A-7C21-4CCB-B16E-0FB37137C16C}
5 | EndProjectSection
6 | EndProject
7 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "appserver", "appserver.vcproj", "{1F726B88-8807-4E99-9982-CCE33198BEE8}"
8 | ProjectSection(ProjectDependencies) = postProject
9 | {D84D100A-7C21-4CCB-B16E-0FB37137C16C} = {D84D100A-7C21-4CCB-B16E-0FB37137C16C}
10 | EndProjectSection
11 | EndProject
12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recvfile", "recvfile.vcproj", "{3D73B2C7-9C2A-4901-9714-03FFB9367644}"
13 | ProjectSection(ProjectDependencies) = postProject
14 | {D84D100A-7C21-4CCB-B16E-0FB37137C16C} = {D84D100A-7C21-4CCB-B16E-0FB37137C16C}
15 | EndProjectSection
16 | EndProject
17 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sendfile", "sendfile.vcproj", "{88AFBB12-0392-4210-A89C-E932BE3AB2E0}"
18 | ProjectSection(ProjectDependencies) = postProject
19 | {D84D100A-7C21-4CCB-B16E-0FB37137C16C} = {D84D100A-7C21-4CCB-B16E-0FB37137C16C}
20 | EndProjectSection
21 | EndProject
22 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "udt", "udt.vcproj", "{D84D100A-7C21-4CCB-B16E-0FB37137C16C}"
23 | ProjectSection(ProjectDependencies) = postProject
24 | EndProjectSection
25 | EndProject
26 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{C70F9A98-ECFF-4DC7-895D-0E41936BD1BA}"
27 | ProjectSection(ProjectDependencies) = postProject
28 | EndProjectSection
29 | EndProject
30 | Global
31 | GlobalSection(SolutionConfiguration) = preSolution
32 | Debug = Debug
33 | Release = Release
34 | EndGlobalSection
35 | GlobalSection(ProjectConfiguration) = postSolution
36 | {4C848417-B545-468B-AA0C-44EE73BC7B9B}.Debug.ActiveCfg = Debug|Win32
37 | {4C848417-B545-468B-AA0C-44EE73BC7B9B}.Debug.Build.0 = Debug|Win32
38 | {4C848417-B545-468B-AA0C-44EE73BC7B9B}.Release.ActiveCfg = Release|Win32
39 | {4C848417-B545-468B-AA0C-44EE73BC7B9B}.Release.Build.0 = Release|Win32
40 | {1F726B88-8807-4E99-9982-CCE33198BEE8}.Debug.ActiveCfg = Debug|Win32
41 | {1F726B88-8807-4E99-9982-CCE33198BEE8}.Debug.Build.0 = Debug|Win32
42 | {1F726B88-8807-4E99-9982-CCE33198BEE8}.Release.ActiveCfg = Release|Win32
43 | {1F726B88-8807-4E99-9982-CCE33198BEE8}.Release.Build.0 = Release|Win32
44 | {3D73B2C7-9C2A-4901-9714-03FFB9367644}.Debug.ActiveCfg = Debug|Win32
45 | {3D73B2C7-9C2A-4901-9714-03FFB9367644}.Debug.Build.0 = Debug|Win32
46 | {3D73B2C7-9C2A-4901-9714-03FFB9367644}.Release.ActiveCfg = Release|Win32
47 | {3D73B2C7-9C2A-4901-9714-03FFB9367644}.Release.Build.0 = Release|Win32
48 | {88AFBB12-0392-4210-A89C-E932BE3AB2E0}.Debug.ActiveCfg = Debug|Win32
49 | {88AFBB12-0392-4210-A89C-E932BE3AB2E0}.Debug.Build.0 = Debug|Win32
50 | {88AFBB12-0392-4210-A89C-E932BE3AB2E0}.Release.ActiveCfg = Release|Win32
51 | {88AFBB12-0392-4210-A89C-E932BE3AB2E0}.Release.Build.0 = Release|Win32
52 | {D84D100A-7C21-4CCB-B16E-0FB37137C16C}.Debug.ActiveCfg = Debug|Win32
53 | {D84D100A-7C21-4CCB-B16E-0FB37137C16C}.Debug.Build.0 = Debug|Win32
54 | {D84D100A-7C21-4CCB-B16E-0FB37137C16C}.Release.ActiveCfg = Release|Win32
55 | {D84D100A-7C21-4CCB-B16E-0FB37137C16C}.Release.Build.0 = Release|Win32
56 | {C70F9A98-ECFF-4DC7-895D-0E41936BD1BA}.Debug.ActiveCfg = Debug|Win32
57 | {C70F9A98-ECFF-4DC7-895D-0E41936BD1BA}.Debug.Build.0 = Debug|Win32
58 | {C70F9A98-ECFF-4DC7-895D-0E41936BD1BA}.Release.ActiveCfg = Release|Win32
59 | {C70F9A98-ECFF-4DC7-895D-0E41936BD1BA}.Release.Build.0 = Release|Win32
60 | EndGlobalSection
61 | GlobalSection(ExtensibilityGlobals) = postSolution
62 | EndGlobalSection
63 | GlobalSection(ExtensibilityAddIns) = postSolution
64 | EndGlobalSection
65 | EndGlobal
66 |
--------------------------------------------------------------------------------
/utest_server/SendMsgBufTest.h:
--------------------------------------------------------------------------------
1 | // SendMsgBufTest.h
2 | #ifndef _UDT_SEND_MSG_BUF_TEST_H_
3 | #define _UDT_SEND_MSG_BUF_TEST_H_
4 |
5 | #include
6 |
7 | class SendMsgBufTest : public CPPUNIT_NS::TestFixture
8 | {
9 | CPPUNIT_TEST_SUITE( SendMsgBufTest );
10 | CPPUNIT_TEST( test_constructor );
11 | CPPUNIT_TEST( test_AddGetHasMsg );
12 | CPPUNIT_TEST( test_PeekFrontMsg );
13 | CPPUNIT_TEST( test_PopMsg );
14 | CPPUNIT_TEST( test_CleanMsg );
15 | CPPUNIT_TEST( test_CleanAllMsg );
16 | CPPUNIT_TEST_SUITE_END();
17 |
18 | public:
19 | void setUp();
20 | void tearDown();
21 |
22 | void test_constructor();
23 | void test_AddGetHasMsg();
24 | void test_PeekFrontMsg();
25 | void test_PopMsg();
26 | void test_CleanMsg();
27 | void test_CleanAllMsg();
28 | };
29 |
30 | #endif // _UDT_SEND_MSG_BUF_TEST_H_
31 |
--------------------------------------------------------------------------------
/utest_server/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 |
9 | int
10 | main( int argc, char* argv[] )
11 | {
12 | // Create the event manager and test controller
13 | CPPUNIT_NS::TestResult controller;
14 |
15 | // Add a listener that colllects test result
16 | CPPUNIT_NS::TestResultCollector result;
17 | controller.addListener( &result );
18 |
19 | // Add a listener that print dots as test run.
20 | CPPUNIT_NS::BriefTestProgressListener progress;
21 | controller.addListener( &progress );
22 |
23 | // Add the top suite to the test runner
24 | CPPUNIT_NS::TestRunner runner;
25 | runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
26 | runner.run( controller );
27 |
28 | // Print test in a compiler compatible format.
29 | CPPUNIT_NS::CompilerOutputter outputter( &result, CPPUNIT_NS::stdCOut() );
30 | outputter.write();
31 |
32 | return result.wasSuccessful() ? 0 : 1;
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/utest_server/test_def.h:
--------------------------------------------------------------------------------
1 | #ifndef _DD_TEST_DEF_H__
2 | #define _DD_TEST_DEF_H__
3 |
4 | #define _SKIP_ASSERT_UNIT_TEST
5 |
6 |
7 |
8 |
9 |
10 | #ifdef _SKIP_ASSERT_UNIT_TEST
11 | #undef CPPUNIT_ASSERT_THROW
12 | #define CPPUNIT_ASSERT_THROW(a, b) __noop_()
13 | inline void __noop_(void) {}
14 | #endif
15 |
16 | #define CPPUNIT_ASSERT_CHECKING_THROW(condition) { CPPUNIT_ASSERT_THROW((condition), AssertException); }
17 |
18 |
19 | #endif // _DD_TEST_DEF_H__
20 |
--------------------------------------------------------------------------------
/utest_server/test_util.cpp:
--------------------------------------------------------------------------------
1 | #include "test_util.h"
2 | #include
3 |
4 | std::string test_str(const std::string& str_prefix, const size_t str_len)
5 | {
6 | std::ostringstream ostr;
7 | ostr << str_prefix << ':';
8 | std::string str = ostr.str();
9 |
10 | // when len <= prefixLen
11 | // test_str(adfadf, 3) == adf
12 | if (str.size() >= str_len)
13 | {
14 | str.resize(str_len);
15 | return str;
16 | }
17 |
18 | // when len < 20
19 | // test_str(adf, 13) == adfa:67890123
20 | if (str_len < 20)
21 | {
22 | for (size_t i = str.size() + 1; i <= str_len; ++i)
23 | str.push_back(char(((i % 10) + 0x30)));
24 | return str;
25 | }
26 |
27 | // when len >= 20
28 | // test_str(asdf, 45) = asdf:=====(20_56789)(30_56789)12345
29 | {
30 | // asdf:=====
31 | str.resize(10, '=');
32 |
33 | // (20_56789)(30_56789)
34 | while (str.size() + 10 <= str_len)
35 | {
36 | const size_t new_len = str.size() + 10;
37 | std::ostringstream tmp_ostrm;
38 | tmp_ostrm << str << "(" << new_len << '_';
39 | str = tmp_ostrm.str();
40 | for (size_t i = str.size() + 1; i < new_len; ++i)
41 | str.push_back(char(((i % 10) + 0x30)));
42 | str += ')';
43 | }
44 |
45 | // 12345
46 | if (str.size() < str_len)
47 | {
48 | for (size_t i = str.size() + 1; i <= str_len; ++i)
49 | {
50 | char c = ((i % 10) + 0x30);
51 | str.push_back(c);
52 | }
53 | }
54 | return str;
55 | }
56 |
57 | return str;
58 | }
59 |
--------------------------------------------------------------------------------
/utest_server/test_util.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _DD_TEST_UTIL_H__
3 | #define _DD_TEST_UTIL_H__
4 | #include
5 |
6 | // when len <= prefixLen
7 | // test_str(adfadf, 3) == adf
8 | // when len < 20
9 | // test_str(adf, 13) == adfa:67890123
10 | // when len >= 20
11 | // test_str(asdf, 45) = asdf:=====(20_56789)(30_56789)12345
12 | std::string test_str(const std::string& str_prefix, const size_t str_len);
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/utest_server/test_util_test.cpp:
--------------------------------------------------------------------------------
1 | // db_imp_test.cpp
2 | #include
3 |
4 | #include
5 | #include "test_util_test.h"
6 |
7 | #include "test_def.h"
8 | #include "test_util.h"
9 |
10 | // Registers the fixture into the 'registry'
11 | CPPUNIT_TEST_SUITE_REGISTRATION( TestUtilTest );
12 |
13 |
14 | void TestUtilTest::test_test_str()
15 | {
16 | // when len <= prefixLen
17 | // test_str(adfadf, 3) == adf
18 | {
19 | CPPUNIT_ASSERT(test_str("asdf", 3) == "asd");
20 | CPPUNIT_ASSERT(test_str("asdf", 4) == "asdf");
21 | CPPUNIT_ASSERT(test_str("asdf", 5) == "asdf:");
22 | }
23 |
24 | // when len < 20
25 | // test_str(adf, 13) == adfa:67890123
26 | {
27 | CPPUNIT_ASSERT(test_str("asdf", 7) == "asdf:67");
28 | CPPUNIT_ASSERT(test_str("asdf", 9) == "asdf:6789");
29 | CPPUNIT_ASSERT(test_str("asdf", 10) == "asdf:67890");
30 | CPPUNIT_ASSERT(test_str("asdf", 11) == "asdf:678901");
31 | CPPUNIT_ASSERT(test_str("asdf", 19) == "asdf:67890123456789");
32 | CPPUNIT_ASSERT(test_str("1234567890123", 19) == "1234567890123:56789");
33 | CPPUNIT_ASSERT(test_str("123456789012345678", 19) == "123456789012345678:");
34 | }
35 |
36 | // when len >= 20
37 | // test_str(asdf, 45) = asdf:=====(20_56789)(30_56789)12345
38 | {
39 | // 20
40 | {
41 | CPPUNIT_ASSERT(test_str("123", 20) == "123:======(20_56789)");
42 | CPPUNIT_ASSERT(test_str("123456789", 20) == "123456789:(20_56789)");
43 | CPPUNIT_ASSERT(test_str("1234567890", 20) == "1234567890(20_56789)");
44 | CPPUNIT_ASSERT(test_str("123456789012345", 20) == "1234567890(20_56789)");
45 | }
46 |
47 | // < 30
48 | {
49 | CPPUNIT_ASSERT(test_str("123", 21) == "123:======(20_56789)1");
50 | CPPUNIT_ASSERT(test_str("123", 23) == "123:======(20_56789)123");
51 | CPPUNIT_ASSERT(test_str("123", 29) == "123:======(20_56789)123456789");
52 | }
53 |
54 | // >= 30
55 | {
56 | CPPUNIT_ASSERT(test_str("123", 30) == "123:======(20_56789)(30_56789)");
57 | CPPUNIT_ASSERT(test_str("123", 31) == "123:======(20_56789)(30_56789)1");
58 | CPPUNIT_ASSERT(test_str("123", 45) == "123:======(20_56789)(30_56789)(40_56789)12345");
59 | CPPUNIT_ASSERT(test_str("123", 129) == "123:======(20_56789)(30_56789)(40_56789)(50_56789)(60_56789)(70_56789)(80_56789)(90_56789)(100_6789)(110_6789)(120_6789)123456789");
60 | CPPUNIT_ASSERT(test_str("123", 129).size() == 129);
61 | CPPUNIT_ASSERT(test_str("123", 1239).size() == 1239);
62 | CPPUNIT_ASSERT(test_str("123", 12390).size() == 12390);
63 | //CPPUNIT_ASSERT(test_str("123", 123903).size() == 123903); // too slow
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/utest_server/test_util_test.h:
--------------------------------------------------------------------------------
1 | // DataFileTest.h
2 | #ifndef TEST_UTIL_TEST_H
3 | #define TEST_UTIL_TEST_H
4 |
5 | #include
6 |
7 | class TestUtilTest : public CPPUNIT_NS::TestFixture
8 | {
9 | CPPUNIT_TEST_SUITE( TestUtilTest );
10 | CPPUNIT_TEST( test_test_str );
11 | CPPUNIT_TEST_SUITE_END();
12 |
13 | public:
14 | void test_test_str();
15 | };
16 |
17 | #endif // TEST_UTIL_TEST_H
18 |
--------------------------------------------------------------------------------