萬惡的網(wǎng)絡(luò)服務(wù)器的項(xiàng)目做完了,昨晚調(diào)試好程序之后,感覺自己又老了一大截,就像阿科一直說的那樣,IT男傷不起啊。
本次項(xiàng)目是網(wǎng)絡(luò)終端管理系統(tǒng),程序代碼不多,就是網(wǎng)絡(luò)協(xié)議,線程等把人都快搞瘋了。項(xiàng)目很簡單,做一個(gè)網(wǎng)絡(luò)服務(wù)器,有服務(wù)端和客戶端,客戶端連接上服務(wù)器之后,能夠注冊登錄,多客戶端連接,有心跳機(jī)制,有配置文件,客戶端發(fā)送shell命令能夠在客戶端顯示,客戶端有聊天功能,類似QQ,所有日志文件和聊天信息均保存。 這次項(xiàng)目沒有規(guī)劃好時(shí)間,起初很快就把基本的框架和注冊登錄寫好了,后來幾天沒有做多少東西,一直以為時(shí)間還多,等到最后真的是不夠了哇。昨天還和理武兄去上海植物園逛了一圈;貋砝^續(xù)寫代碼,一直到凌晨兩點(diǎn)。 第一個(gè)問題是shell 命令,起初shell命令寫好了,重定向到客戶端屏幕顯示正常,輸入ls的時(shí)候可以用,但是pstree –p的時(shí)候就不行了,經(jīng)檢查后當(dāng)發(fā)現(xiàn)邏輯有一定問題,緩存空間太小,必須循環(huán)讀取數(shù)據(jù)。后來雖然是能夠循環(huán)讀寫了,但是忘記加結(jié)束符’\0’,命令顯示也不正常。 第二個(gè)問題是心跳機(jī)制,所謂心跳機(jī)制就是客戶端連接服務(wù)器之后,隔一段時(shí)間向服務(wù)器發(fā)送一個(gè)信號,表示該用戶在線,當(dāng)用戶意外退出或者無操作時(shí),服務(wù)器端的心跳處理函數(shù)開始處理,定時(shí)器時(shí)間到了就會(huì)把客戶端用戶置為不在線狀態(tài)。我想了一個(gè)很簡單的辦法,在用戶鏈表里面設(shè)了一個(gè)heart,注冊時(shí)置-1,正常退出置-1,在客戶端用alarm函數(shù),循環(huán)向服務(wù)器發(fā)信號,如果服務(wù)器收到信號,就將heart置為10,服務(wù)器心跳處理函數(shù)就是當(dāng)heart為10時(shí),用戶在線正常,當(dāng)heart>0時(shí),heart減1,heart=0時(shí)用戶離線成功。服務(wù)器也是用alarm函數(shù)循環(huán)處理心跳。 第三個(gè)問題是線程,起初客戶端只開了兩個(gè)線程,其中一個(gè)線程只處理聊天信息,但是在退出聊天的時(shí)候,無法正常退出。當(dāng)時(shí)我在想,主線程和子線程應(yīng)該是同時(shí)讀取服務(wù)器發(fā)來的信號,后來經(jīng)過我很多次的實(shí)驗(yàn),發(fā)現(xiàn)在子線程發(fā)給服務(wù)器的信號,只有子線程能接收到,這樣我就想了一個(gè)辦法,先結(jié)束子線程,再用pthread_join回收子線程資源,然后在主線程發(fā)送一個(gè)信號給服務(wù)器,這樣主線程就能讀取到服務(wù)器的信號了。后來我用了三個(gè)線程,兩級菜單兩個(gè)線程,處理聊天信息一個(gè)線程,其中一個(gè)我用了return結(jié)束子線程,還有一個(gè)用了pthread_exit結(jié)束子線程,都成功了。不知道我的想法對不對。 pthread_join的作用:使一個(gè)線程等待另一個(gè)線程結(jié)束。代碼中如果沒有pthread_join主線程會(huì)很快結(jié)束從而使整個(gè)進(jìn)程結(jié)束,從而使創(chuàng)建的線程沒有機(jī)會(huì)開始執(zhí)行就結(jié)束了。加入pthread_join后,主線程會(huì)一直等待直到等待的線程結(jié)束自己才結(jié)束,使創(chuàng)建的線程有機(jī)會(huì)執(zhí)行。 第四個(gè)問題是保存和讀取文件的問題。以前做項(xiàng)目都是保存二進(jìn)制文件,這次保存日志文件和讀取配置文件。經(jīng)百度之后知道了操作文本文件的辦法。保存代碼: printf(fd,”%s”,buf); printf(fd,”%d”,i); fprintf用法和printf用法一樣,多了一個(gè)文件描述符。 讀取代碼如下: FILE *fp; fp = fopen(“./ip”,”r”); while(!feof(fp)) ipbuf[i++]=getc(fp); ipbuf[i-2]= ‘\0’; fopen第一個(gè)參數(shù)是文件路徑。ipbuf里面存放的就是ip文件的數(shù)據(jù)。 第五個(gè)問題是獲取系統(tǒng)時(shí)間,保存日志文件時(shí),保存項(xiàng)目有ip、用戶、操作、操作時(shí)間。操作時(shí)間就是系統(tǒng)時(shí)間咯,代碼如下: #include<time.h> #include<stdio.h> char *buf = NULL; time_t now; struct tm *timenow; time(&now); timenow=localtime(&now); printf("time : %s\n",asctime(timenow)); buf = asctime(timenow); printf("buf:%s\n",buf); 第六點(diǎn)就是字節(jié)序?qū)R問題。到現(xiàn)在還不是很理解,需要在再深入理解一下。 軟件運(yùn)行暫時(shí)能夠?qū)崿F(xiàn)項(xiàng)目的要求。這次沒做好的很重要的一點(diǎn)就是,沒有時(shí)間寫代碼注釋了,代碼存放得相當(dāng)亂,因?yàn)樾薷牧撕芏啻,宏定義和函數(shù)名、變量名等取名很垃圾。網(wǎng)絡(luò)數(shù)據(jù)包傳送的無用東西太多,為了圖方便,所有信息全部存在了數(shù)據(jù)包里面,占用了大量的網(wǎng)絡(luò)資源。還有一個(gè)重要的問題是線程沒有做同步浪費(fèi)了內(nèi)核資源。
|