記這難忘的一個月

來源:互聯網
上載者:User

剛寫這個程式的時候,無從下手之中又夾雜著一點興奮,整天腦子裡想的都是該怎麼設計伺服器,怎麼設計資料庫,資料庫中該有哪些欄位,怎麼去設計用戶端,怎麼才能讓伺服器儲存使用者的好友資訊等等,太多太多了,不斷地想到方法,又不斷地推翻自己,雖然我當時什麼都不懂,但也沒上網查,我覺得我喜歡這種設計的感覺(當然,後來事實證明知道的太少了,還是從網上知道了資料庫該怎麼設計)。最開始糾結我的還是用戶端的訊息到底經不經過伺服器,問了好多人,各有各的說法,最後黃學長給我說馬學長做過做個程式,就去問了問他,他告訴我登陸的時候和伺服器通訊,然後和好友聊天的時候就直接用udp模式給好友發資訊了,不經過伺服器(雖然這樣說,但是我還是不明白,我們有時候在QQ上不能發禁用語,如果不經過伺服器,那他是怎麼檢測到的呢。)

寫這個程式之前,網路編程方面的程式,我就寫過書上那幾個,那種最最最基本的“你點send,我點receive”的程式,甚至連c/s模式的都沒寫過,更別說這個程式的非同步通訊端了。開始那會兒都是特別天真的,以為把書上的那種通訊模式寫成c/s模式就可以了,現實是殘酷的,我再次遭遇了阻塞函數的困擾,當時在看書的時候學長就給我說過accept和receive會阻塞,說實話當時並沒有深刻的理解,後來自己看到線程那章的時候,就想過創一個線程來接收使用者發過來的訊息,當時就只是想了想,這次想付諸於行動,正好手邊的一本,也是唯一帶回來的一本vc的書——孫鑫的《VC++深入詳解》,這是我從學長那兒借來的書,這一個月多虧了這本書,好多好多東西都是從上面借鑒的,包括後面的非同步通訊端;言歸正傳,在面臨阻塞函數的困擾時,我想用多線程來解決這個問題,在這個過程中,遇到了好多問題,比如:

因為基礎不好,所以當時看到這個之後,想的就是是不是自己函數定義或者聲明出了問題,不斷地找啊找,都找不到那出錯了,後來是因為在定義成員函數的時候,

必須手動輸入,不能複製!!!

在調試最開始的通訊代碼中,發現用戶端那邊線程並沒有阻塞,後來上網問了才知道是因為沒綁定通訊端(當時連這種錯誤都要犯,一些概念性的東西真是沒掌握)

中間還遇到了通訊端相互賦值的問題,因為CSocket類沒有重載=,所以不能通過socket1=socket2這樣簡單地把socket2賦給socket1,上網查到可以用detach和attach來實現通訊端的傳遞,但是detach之後,原來的通訊端就被關閉了,不是我想要的。

有天在網上了篇文章,上面說到:

“曾經看到有人自己建立線程,線上程中建立CSocket對象進行Listen、Accept,若Accept成功則再起一個線程繼續Listen、Accept。。。可以說他完全不理解CSocket,實際上CSocket已經內建了多線程機制,你只需要從CSocket派生,然後重載OnAccept:”

我一直就是那個不理解CSocket的人,我一直都是Accept成功則再起一個線程繼續Listen、Accept。。。因為我當時甚至不知道監聽通訊端僅僅是用於監聽的(因為這個問題,還在csdn上被人吼了一頓)........後來弄了兩天,發現創了線程之後有好多細節的地方,比如入口函數必須是全域函數或者靜態函數,而靜態函數又有很多要注意的細節,說實話,自己基礎太差了,在網路編程這塊兒都還沒掌握好的前提下,再涉及線程這些東西,真的有點困難。後來再次翻閱孫鑫的《VC++深入詳解》,線上程同步這章的後面,發現了一個基於訊息的非同步通訊端的網路聊天室程式,不斷地研究那個程式,當時還沒用過socket類,因為前一本書上網路編程這塊都是用的csocket類,所以在看到載入通訊端,以及SOCKETADD_IN類型的時候都會特別迷糊,不過後來多看幾遍也就習慣了。在這個程式中,首先要用WSAAsyncselect()函數為指定的通訊端註冊一個網路事件,這個地方犯了一個到最後才發現的問題,就是在伺服器端我居然就為監聽通訊端註冊了網路事件,不光註冊了FD_Connect,還註冊了FD_Read這個事件,真是因為這方面知識太少了,我當時還以為只要註冊了網路事件,不管是哪個通訊端,只要有訊息來,就會觸發事件,後來就導致了一些問題,這些後面再說。照著書上的葫蘆,我也畫了一個初步的瓢,一個簡單的基於訊息的非同步通訊端。第一階段算是結束了。

第二階段是資料庫的操作。特別不幸的是,孫鑫的《VC++深入詳解》中,關於資料庫的操作基本沒講,又找到那本《21天學通vc++》,上面主要講了用ODBC對資料庫進行操作,但是講得也很淺,跑到我們這邊的書店轉了轉,居然沒有資料庫編程相關的書,沒辦法只有用ODBC嘗試,而這時困擾我的還有另一個問題,就是資料庫的設計,主要是好友這塊,我當時還沒想到用兩張表,想的就是在一張表記憶體使用者的基本資料,以及他的好友,後來發現好友不只一個,那豈不是要建很多欄位(好友1,好友2,好友3......),當然這一點都不實際,又想過資料庫中欄位有沒有類似於數組的類型,最後實在沒辦法,就問問了學長,學長說建兩個表,一個存使用者資訊,一個存好友關係。雖然這樣說,但是還是有迷惑,使用者多了之後,那好友關係那張表資料不是會很大嗎。而且伺服器要遍曆一次多費勁呀。當時兩張表的關鍵字都是設的QQ,後來又發現一個問題,就是我好友關係表的QQ欄位裡的記錄可能會有重複的,但是關鍵字是不允許重複的,而且此時我試了試遍曆一張表(當時表裡只有兩條資料),奇怪的是,出現結果卻是4條,就是這兩條資料的不同組合,上網查了查,發現是笛卡爾積,兩張表串連的時候,會遵循笛卡爾積的規則。當時的一個想法就是怎麼只在一張表中操作,網上一問,好心的網友回答了很多,但是odbc書上講得太少了,他們講那些我真是一點都看不明白,沒辦法,身邊能看的書都看了,只剩下《vc++深入詳解》中那一丁兒點關於ADO操作資料庫的了,開始還想,就這麼幾頁,看了肯定也沒用,還是回學校之後再去借專門資料庫的書來看吧。但是抱著死馬當活馬醫的想法,還是看了一點,誰知道那天晚上這麼一看,充分地明白了為什麼現在ADO這麼盛行了,果然比起ODBC太方便了,看完之後立馬從床上下來開啟電腦開始寫書上的程式,當看到ADO通過 rst1->Open(  "select *from QQ帳號資訊表", _variant_t ((IDispatch*)con,true),adOpenStatic,adLockOptimistic,-1 );直接獲得某個指定的表的指標時,真有一種絕境逢生的感覺。

第三階段就是自己設計協議了(不知道能不能算是協議)。當時遇到的問題就是,使用者要發給伺服器很多訊息,比如登陸時的帳號和密碼訊息,比如註冊時的訊息,或者添加好友的資訊。其實這個問題從最開始就困擾我,直到我有次嘗試著發送結構體,因為send和receive函數buf都是char *型的,所以當時不知道怎麼髮結構體,網上說強制轉換就行,但是好多細節還是不明白,最後還是csdn上的一位網友教會了我,有了這次發送結構體的經驗,加上看到網上的說可以自訂包頭來區分這些訊息,包頭裡是標示符。說實話我對包頭沒什麼概念,但是當時我的第一個想法就是,用結構體,定義一個成員flag,用來標示這些訊息。比如用戶端發送的訊息中flag為10,就是登陸資訊,20就是註冊資訊,30就是添加好友的資訊,40就是請求重新整理好友的資訊。當時我突然覺得有點明白協議是什麼意思了。身在北郵,但是卻沒學過通訊方面的課程,整天聽其他院的同學說著什麼協議協議,我記得我有次還問過一個信通的同學,協議到底是什麼,他給我的回覆就是雙方定好的一種規則。我當時就在想,字面意思就是這樣,但是對於實際中的協議到底是什麼,我還真是一點概念都沒有,這次沒想到自己居然就這樣定義了一個“協議”。但是我還是覺得不妥,這個程式簡單,所以就幾種類型的訊息,要是以後功能多了,還能這樣約定嗎。我想也許會有更好的方法吧。這段時間遇到的幾個大的問題上面已經說了,還有一個就是使用者如何即時擷取自己好友訊息,想了很久,最後還是用了定時器來實現,每隔一段時間(程式裡是1分鐘,方便調試驗)就向伺服器發送一個請求,請求重新整理自己的好友,伺服器就去資料庫中尋找他好友裡面線上的人的資訊,然後發給使用者。

程式還有幾個帶完善的問題,首先就是伺服器如何判斷使用者是否線上的問題,其次是用戶端處於好友介面時,怎麼提醒使用者來了一條訊息,因為我chat的通訊端是在chat視窗中建立的,所以如果chat視窗沒開啟,通訊端也就不會建立,也就不會收到好友發的訊息;

最後在網上找了一個托盤程式,實現了程式能夠最小化到右下角的托盤地區;

聯繫我們

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