網速測試

來源:互聯網
上載者:User

    好久不來寫BLOG了,最近在寫一個檔案傳送的程式,可是在發檔案中使用fread去讀取檔案,如果定義的緩衝不合適當時的網速就會出問題,設定過小,每次傳送的檔案就非常小,設定過大,在另一端寫檔案就可能沒有完整的寫完上步的內容,緊接著下一步內容就傳過來。當然我們都不希望出現這樣的結果。於是就寫了一個測試網速的程式。

    其實大體步驟就是一下:

WINSOCK C/S的建立過程:

     伺服器                         用戶端
________________________________________________
1   初始化WSA                      1   初始化WSA
____________________________________________________
2   建立一個SOCKET                 2   建立一個SOCKET
_____________________________________________________
3   綁定SOCKET                     3   串連到伺服器
_____________________________________________________
4   在指定的連接埠監聽               4   發送和接受資料
_____________________________________________________
5   接受一個串連                   5    中斷連線
______________________________________________________-
6   發送和接受資料
___________________________________________________
7   中斷連線
__________________________________________________

    我是一個新手,當然存在很多不曉得的知識,也遇到了不少問題,下面我就我遇到的問題概括一下:

    1,初始化WSA。以前從未接觸過SOCKET傳檔案,一看見初始化,不就是要定義嗎?所以就在網上找了半天,什麼也沒找到,後來經我哥解釋,方才知曉,原來#include “winsock.h”中已經涵蓋了WSA 資訊,無非就是

int  nRet;
 //初始化
 WSADATA wsaData;

 nRet = WSAStartup(514, &wsaData);//wsaData用來儲存系統傳回的關於WINSOCK的資料

 if (nRet != 0)
 {
  printf("WSAStartup error!/n");//傳回值不等於0,說明初始化失敗
  return 0;
 }網上現成的,當然一開始我也找到了,可是開始時就是不知道為什麼要這樣就是初始化。畢竟是新手麼。

    2,建立一個SOCKET。

//建立SOCKET結構
 SOCKET m_socket;//建立一個m_socket的SOCKET控制代碼

 m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);     //建立TCP協議,傳回值儲存在m_socket中

 //以下代碼用於檢查傳回值是否有錯誤
 if(m_socket == INVALID_SOCKET)
 {
  printf("Error at socket():%d/n",GetLastError());
  WSACleanup();                                    //釋放資源
  return 1;                                    //如果socket()調用失敗,他將返回INVALID_SOCKET
 } //應用程式在完成對請求的SOCKET庫使用後,要調用WSACleanup函數來結束SOCKET庫的綁定,並且釋放資源.
這一步倒還是能大概瞭解一下,也都能看的懂。

    3,綁定SOCKET。就是使用bind函數進行操作,這一步就是要綁定我們的IP。當然服務端和用戶端都要使用服務端的IP。我這用了一個自動獲得IP的函數(內網和外網的都能獲得)。在IP這我想說幾句,我們如果使用路由器上網,我們所用的IP就有兩種,一個是針對外網的IP,一個是針對路由器內使用者的IP。我是使用路由器上網的,但是發現目前自己的程式還是不能測試A路由器中的使用者和B路由器中使用者之間的網速。起碼我目前是做不到,還請看到文章的同志們能給詳細的介紹個好方法。

    4 ,在指定的連接埠監聽。當綁定完成後,伺服器必須建立一個監聽隊列,以接受用戶端的請求。listen()使伺服器進入監聽狀態,該函數調用成功返回0,否則返回 。一旦伺服器開始監聽,我們就要指定一個控制代碼來表示利用ACCEPT()函數接受的串連,這個控制代碼是用來發送和接受資料的表示。還需建立一個SOCKET控制代碼 。Socket AcceptSocket 然後利用無限迴圈來檢測是否有串連傳入。

    5, 接受一個串連。一但有串連請求,ACCEPT()函數就會被調用,並且返回這次串連的控制代碼.。

SOCKET AcceptSocket;
 AcceptSocket = SOCKET_ERROR;
 while(AcceptSocket==SOCKET_ERROR)
 {
  AcceptSocket=accept(m_socket,NULL,NULL);
  printf("Get connect!/n");
  break;
 }
 
 SOCKET m_server;
 m_server = AcceptSocket;

    6,發送和接受資料。在控制台裡用ping測試回應時間是電腦使用的是32位元組,所以我們就定義一個32位元組長度的字串,並申請兩個長度為33的緩衝,並將字串放到其中一個緩衝內,傳送資料中,我們使用的是5次迴圈,在服務端用GetTickCount()獲得當前的CPU轉數,一次迴圈後再調用函數GetTickCount()獲得一次轉數,兩者之差即為一次傳送中CPU轉過的圈數,也就對應了一個傳送32位的時間,最後得到5次迴圈的平均值。用戶端使用的是死迴圈,並且把接收到的資料重新send到服務端,並和服務端的緩衝strcmp(),如果是為0就代表用戶端返回正確,也就是一次迴圈成功,但是網路中有可能斷線,此時我採用的處理方法是:發送成功時recv的傳回值是字串的長度,失敗則是返回-1,於是我就使用DWORD dwerror = WSAGetLastError ()獲得dwerror,如果其值為0x2746,則表示網路出問題,我們就跳出迴圈,重新檢測。用戶端也可以使用同樣的方法進行判斷網路問題,當然用戶端還要使用recv函數的傳回值退出死迴圈,條件就是recv傳回值為0,也就是接受不到任何資料。我們得到了傳送32位位元組的平均時間也就能得到每秒能傳送多少位元組了。

    7, 中斷連線。釋放緩衝free,釋放連接埠closesocket。最後 WSACleanup()。

 

對此函數感興趣的話,請到本人自願下載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.