TTCP程式原始碼剖析

2021-09-26 06:51:35 字數 4442 閱讀 9211

1、ttcp作用:檢測tcp吞吐量

測試的資料是每秒傳輸的位元組數

頻寬 mb/s

測試程式的效能指標: 傳輸頻寬,qps/tps, 以及 cpu利用率,延遲等等。

2、ttcp應用層協議:

3. 嘗試自己用c語言寫出簡單的ttcp程式

先傳送乙個sessionmessage包中number表示訊息的條數,length表示每條訊息的長度

payloadmessage包中存放資料的長度和資料

服務端接收函式

void receive(const options& opt)

; if (read_n(sockfd, &sessionmessage, sizeof(sessionmessage)) != sizeof(sessionmessage))

sessionmessage.number = ntohl(sessionmessage.number);

sessionmessage.length = ntohl(sessionmessage.length);

printf("receive number = %d\nreceive length = %d\n",

sessionmessage.number, sessionmessage.length);

const int total_len = static_cast(sizeof(int32_t) + sessionmessage.length);

payloadmessage* payload = static_cast(::malloc(total_len));

assert(payload);

for (int i = 0; i < sessionmessage.number; ++i)

payload->length = ntohl(payload->length);

assert(payload->length == sessionmessage.length);

if (read_n(sockfd, payload->data, payload->length) != payload->length)

int32_t ack = htonl(payload->length);

if (write_n(sockfd, &ack, sizeof(ack)) != sizeof(ack))

} ::free(payload);

::close(sockfd);

}

先看傳入的物件,封裝了埠等資訊

struct options

};

接收乙個tcp連線

int sockfd = acceptordie(opt.port);
處理第乙個包

這個結構體就是傳送的訊息數,和每條訊息的長度,收到資料後,要轉換一下位元組序

struct sessionmessage

__attribute__ ((__packed__));

struct sessionmessage sessionmessage = ;

if (read_n(sockfd, &sessionmessage, sizeof(sessionmessage)) != sizeof(sessionmessage))

sessionmessage.number = ntohl(sessionmessage.number);

sessionmessage.length = ntohl(sessionmessage.length);

printf("receive number = %d\nreceive length = %d\n",

sessionmessage.number, sessionmessage.length);

看看read_n 函式,讀n個位元組資料

static int read_n(int sockfd, void* buf, int length)

else if (nr == 0)

else if (errno != eintr)

} return nread;

}

讀完第乙個包資訊後,生成第二個包的結構體

const int total_len = static_cast(sizeof(int32_t) + sessionmessage.length);

payloadmessage* payload = static_cast(::malloc(total_len));

這裡使用了static_cast代替c風格的強轉

然後讀取多條資料

先看資料報結構體的定義

struct payloadmessage

;

for (int i = 0; i < sessionmessage.number; ++i)

payload->length = ntohl(payload->length);

assert(payload->length == sessionmessage.length);

if (read_n(sockfd, payload->data, payload->length) != payload->length)

int32_t ack = htonl(payload->length);

if (write_n(sockfd, &ack, sizeof(ack)) != sizeof(ack))

} ::free(payload);

::close(sockfd);

傳送一條確認訊息函式,完整寫n個位元組

static int write_n(int sockfd, const void* buf, int length)

else if (nw == 0)

else if (errno != eintr)

} return written;

}

客戶端**

客戶端的邏輯就是連線客戶端,按照規定的應用層協議傳送資料

void transmit(const options& opt)

printf("connecting to %s\n", addr.toipport().c_str());

tcpstreamptr stream(tcpstream::connect(addr));

if (!stream)

if (opt.nodelay)

printf("connected\n");

double start = now();

struct sessionmessage sessionmessage = ;

sessionmessage.number = htonl(opt.number);

sessionmessage.length = htonl(opt.length);

if (stream->sendall(&sessionmessage, sizeof(sessionmessage)) != sizeof(sessionmessage))

const int total_len = sizeof(int32_t) + opt.length;

payloadmessage* payload = static_cast(::malloc(total_len));

std::unique_ptrfreeit(payload, ::free);

assert(payload);

payload->length = htonl(opt.length);

for (int i = 0; i < opt.length; ++i)

double total_mb = 1.0 * opt.length * opt.number / 1024 / 1024;

printf("%.3f mib in total\n", total_mb);

for (int i = 0; i < opt.number; ++i)

double elapsed = now() - start;

printf("%.3f seconds\n%.3f mib/s\n", elapsed, total_mb / elapsed);

}

原始碼剖析 Hashtable 原始碼剖析

hashtable同樣是基於雜湊表實現的,同樣每個元素都是key value對,其內部也是通過單鏈表解決衝突問題,容量不足 超過了閾值 時,同樣會自動增長。hashtable也是jdk1.0引入的類,是執行緒安全的,能用於多執行緒環境中。hashtable同樣實現了serializable介面,它支...

python原始碼剖析 Python原始碼剖析

第頁共 頁python 原始碼剖析 物件機制 1.物件 在python 的世界中,一切都是物件,乙個整數是乙個物件,乙個字串也是 乙個物件,更為奇妙的是,型別也是乙個物件,整數型別是乙個物件,字串類 型也是乙個物件。從 年guido 在那個聖誕節揭開 python 世界的大幕開始,一直到現在,pyt...

Erlang hotwheels原始碼剖析

整體構架 janus transport sup 實質為transport,supervisor,client instance supervisor 每個tcp會話建立乙個transport程序來處理對應客戶端的請求。janus topman sup 實質為topman,worker,topic ...