為一個朋友的代碼進行錯誤修正

來源:互聯網
上載者:User

一位朋友剛開始接觸SOCKET編程,給了一段代碼請我幫忙看看,前面兩個函數如下(注釋是我加的):

void CtransferDlg::OnBnClickedBtnStart() {
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //這裡似乎應該用ntohl()
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(7001); //同理,這裡似乎應該用ntohs()
if (SOCKET_ERROR == bind(sockSrv ,(SOCKADDR*)&addrSrv , sizeof(SOCKADDR))) {
MessageBox("地址邦定失敗!");
return; //這裡直接返回了,sockSrv這個資源未得到釋放
}
if (SOCKET_ERROR == listen(sockSrv , 5)) {
MessageBox("監聽失敗!");
 return; //同樣,如果啟動偵聽失敗,sockSrv這個資源得不到釋放
 }
::CreateThread(NULL, 0, listenThread, (LPVOID)sockSrv, 0, NULL);
//未判斷CreateThread的傳回值,不知道線程是否建立成功。
//未儲存返回的線程控制代碼並且立刻CloseHandle這個控制代碼(問題不大,但這是細節)
//本函數退出了,sockSrv這個資源似乎只有讓新建立的線程來負責釋放,否則……
}

//下面是負責Accept的線程(所以listenThread這個函數名似乎取得有點問題)
DWORD WINAPI CtransferDlg::listenThread(LPVOID lpParameter) {
SOCKADDR_IN addrClient ;
int len = sizeof( SOCKADDR_IN ); //這句應該搬到accept(...)這一句的前面。
//注意下面開始了一個無限迴圈,沒有任何出口
while(TRUE) {
SOCKET sockConn = accept((SOCKET)lpParameter, (SOCKADDR *)&addrClient , &len);
//忘了判斷傳回值,accept也會失敗(比如sockSrv被另一個線程關閉)
char recvBuf[100]; //注意這個緩衝區在棧上,並且由多個用戶端串連共用
recv(sockConn , recvBuf , 100 , 0); //這裡100應該用sizeof(recvBuf)來代替,不應該用寫入程式碼
//同樣也忘了判斷recv()的傳回值,而且,還錯誤地用了阻塞式recv
closesocket(sockConn); //不知道為什麼要立刻斷開用戶端
::CreateThread(NULL, 0, ConnectThread, (LPVOID)recvBuf, 0, NULL);
//建立一個新線程來處理資料,但recvBuf也許會被下一個進來的用戶端發來的資料覆蓋掉
//每一個用戶端串連建立一個線程來處理,也不是一個好辦法
}
//這個迴圈永遠退不出來,而且傳進來的lpParameter其實是sockSrv,
//沒有任何地方會釋放它(closesocket)
return 0;
}

上面兩個函數,問題不少,簡單歸納一下,主要是:

  • 對資源的釋放問題漫不經心
    資源不用了,應該立刻釋放,雖然在進程終止以後,作業系統會回收所有資源,但一個程式(特別是7×24啟動並執行服務端程式)應該做到不出任何一點點泄露。
  • 對多線程理解不深
    多線程編程是個很複雜的邏輯(在對共用資源進行訪問時會遇到各種各樣稀奇古怪的問題),而且對程式效能影響很大(比方說,如果按上面的代碼為每一個用戶端都建立一個線程,如果這些線程都不休眠的話,那CPU被拖得100%佔用率很容易)。
  • 缺乏判斷函數傳回值的習慣
    正確的習慣應該是判斷每一個具有傳回值的函數(如果函數總是成功,其傳回值肯定是void型的)。

今天有點晚了,明天再來寫通常的做法應該是怎樣的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.