發表於
2013/11/25 19:18:27
11819人閱讀
分類: development
下面的程式實現了對 tcp 連線的分流,即將乙個 tcp 連線的流量分布到多個 tcp 連線上進行傳輸。
本程式的主要作用是在特定網路環境下提公升通過 tcp 連線的 openvpn 服務的速率,使之充分利用頻寬。
程式的主要複雜之處在於單生產者—多消費者、多生產者—單消費者兩種同步方式的實現。
#include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
using namespace poco;
using namespace poco::net;
class error_handler : public errorhandler
virtual void exception(const std::exception& exc)
virtual void exception()
};class
char buf[4096];
size_t sz;
while ((sz = fread(buf, 1, 4096, fp)))
out.insert(out.end(), buf, buf + sz);
fclose(fp);
for (size_t i = 0; i < out.size(); ++i)
if (!out[i])
out[i] = ' ';
return 0;
}void split_lines(const vector&in, vector&out)
if (pos < in.size())
out.push_back(string(in.begin() + pos, in.end()));
}void trim_string(string &str)
void split_string(const string &in, vector&out, const char *delims)
}public:
int load(const char *filename)
if (config.find(parts[0]) != config.end())
printf("[!] override config: %s (%d)\n", filename, (int)i + 1);
config[parts[0]] = parts[1];
}return 0;
}int i(const char *key) const
int ret = 0;
if (sscanf(iter->second.c_str(), "%d", &ret) != 1)
printf("[!] invalid int: %s\n", key);
return ret;
}const string & s(const char *key) const
return iter->second;
}} config;
// read from out buffer and send to remote
class reader : public runnable
virtual void run()
catch (exception &exc)
if (sz2 <= 0)
sent += sz2;
}if (closed)
break;
}else
}try catch (...) {}
self_stopped = true;
writable.set();
}};// receive from remote and write to in buffer
class writer : public runnable
virtual void run()
catch (exception &exc)
if (sz <= 0)
break;
int written = 0;
while (written < sz)
else
}if (peer_stopped)
break;
}try catch (...) {}
self_stopped = true;
readable.set();
}};// receive from local and write to out buffers
class divider : public runnable
virtual void run()
catch (exception &exc)
if (sz <= 0)
break;
for (int i = 0; i < nr_conn; ++i)
for (int i = 0; i < sz; ++i)
bufv[(total + i) % nr_conn][szv[(total + i) % nr_conn]++] = buf0[i];
total += sz;
while (true)
}if (!written)
if (peer_stopped)
break;}}
try catch (...) {}
self_stopped = true;
for (int i = 0; i < nr_conn; ++i)
readables[i]->set();
}};// read from in buffers and send to local
class combiner : public runnable
virtual void run()
int sz = 0;
while (true)
total += sz;
if (sz > 0)
}int sent = 0;
while (sent < sz)
catch (exception &exc)
if (sz1 <= 0)
sent += sz1;
}if (closed)
break;
}else
}try catch (...) {}
self_stopped = true;
for (int i = 0; i < nr_conn; ++i)
writables[i]->set();
}};int main(int argc, char **argv)
vectorremotes;
if (config.s("remote") == "listen")
server.close();
}else
}vectorin_buffers, out_buffers;
vectorreaders;
vectorwriters;
thread *reader_threads = new thread[nr_conn], *writer_threads = new thread[nr_conn];
for (int i = 0; i < nr_conn; ++i)
streamsocket local;
if (config.s("local") == "listen")
else
divider *pdivider = new divider(nr_conn, local, out_readables, out_writable, out_buffers, divider_stopped, readers_stopped);
combiner *pcombiner = new combiner(nr_conn, local, in_readable, in_writables, in_buffers, combiner_stopped, writers_stopped);
thread divider_thread, combiner_thread;
divider_thread.setstacksize(65536);
combiner_thread.setstacksize(65536);
divider_thread.start(*pdivider);
combiner_thread.start(*pcombiner);
printf("[.] connection established\n");
fflush(stdout);
divider_thread.join();
combiner_thread.join();
local.close();
for (int i = 0; i < nr_conn; ++i)
printf("[.] connection closed\n");
}catch (exception &exc)
catch (exception &exc)
catch (...)
return 0;
}客戶端網路環境為 cernet ,伺服器是位於達拉斯的 burstnet vps ,連線方式是 tcp/ipv6 。
直接連線, openvpn 速率為 341 kb/s 。使用 5 個連線進行分流, openvpn 速率可達 1.4 mb/s 。
VC 基於TCP 面向連線 的SOCKET程式設計
一 伺服器端程式設計 1 建立套接字 socket 2 將套接字繫結到乙個本地位址和埠 bind 3 將套接字設為監聽模式,準備接收客戶請求 listen 4 等待客戶的請求到來,當請求到來後,接收連線請求,返回乙個新的對應於此次連線的套接字 accept 5 用返回的套接字和客戶端進行通訊 sen...
基於SpringBoot的快速開發框架分享
首先github 介紹一下我的這個專案,這個專案我是去年開始做的,斷斷續續寫了差不多4 5個月 而完善功能之後,也是很久沒有修改過了。這個框架基於rest風格開發,適合做前後端分離的專案,用到的技術也特別注重開發效率,都是選擇了一些可以高效開發並且使用簡單的技術。前段時間使用過thinkphp,自認...
基於XORM框架實現分表
最近在維護公司專案過程中,學習了很多後端的東西,包括go語言以及資料庫的操作。同時站在全域性的角度去體會了高額資料量情況下後端的應對策略,為今後在前端方面如何配合後端處理高併發提供了參考。技術背景 xorm xorm是乙個簡單而強大的go語言orm庫.通過它可以使資料庫操作非常簡便。可以簡單理解成g...