mychatroom聊天室坑點簡要分析

2021-10-08 00:15:37 字數 1948 閱讀 5105

之前寫聊天室的時候,因為構思不夠嚴謹,連續重構了好幾次,也算是踩了好多次的坑。這次就給大家講下我寫聊天室的一點點經驗和建議。

採用的策略:迭代伺服器還是併發伺服器

迭代伺服器

伺服器程序是乙個乙個處理各個客戶端發來的連線的,比如乙個客戶端發來乙個連線,那麼只要它還沒有完成自己的任務,那麼它就一直會占用伺服器的程序直到處理完畢後伺服器關閉掉這個socket。

併發伺服器

我的伺服器大致思路:

我的客戶端大致思路:

注意:其實客戶端同樣是可以用epoll監聽stdin和伺服器套接字。

(另外需要提到的一點就是只能乙個執行緒讀同乙個套接字,你傳送給伺服器檔案,如果讓伺服器開接受檔案的執行緒,這個想法很自然,但是事實上會有點問題:我們在傳送給伺服器檔案的同時,傳送了一條訊息,伺服器的這個執行緒難道不會接受你傳送的訊息嗎?如果想要通過recv 的msg_peek以獲取檔案的flag位來表示訊息型別而不去接收,這同樣會出現問題,乙個執行緒可能一直拿到這個包,另乙個執行緒一直拿不到,而我當時的設計裡伺服器是沒用epoll+執行緒池的,這會導致我整個伺服器阻塞在這!因此recv讓乙個執行緒來做,而send包的時候其實可以開多執行緒因為不存在這種衝突)

訊號怎麼處理

sigpipe

伺服器 server 向已經關閉的 client 繼續傳送資料(其實是傳送兩次才會觸發),大部分訊號都是預設結束整個程式。而伺服器是需要永久掛著的,如果觸發了sigpipe,程式是會停止的,我們得使用sig_ign。

客戶端 使用訊號處理函式通知伺服器提前退出,緊接著客戶端就可以退出了。

sigint,sigterm 都可以選擇性sig_ign

epollrdhup是什麼?這是epoll中可以監聽到的事件種類之一,代表對端的關閉。epoll_wait得到的結果集中,你可以通過這個標誌位來監測客戶端退出,關閉客戶端連線。

應該設計哪些類?mysql設計哪些表?

好友表,訊息表,賬號表…並沒有什麼標準答案,最好想好先邏輯了再去寫,不然很容易重構的。

傳的pack包最好帶有個mysql中id欄位(不過你傳送給伺服器不一定要填寫這個字段),因為我當初沒有加id欄位(因為總感覺這對客戶沒有用)結果在伺服器上處理業務邏輯每次都得根據賬號去查詢mysql下的id,再根據id去做更多操作,比如查詢另一張含有這個id的表。直接**量大了很多很多,也讓程式的結構顯得十分醜陋,可讀性也會很差。

cjson / 自己寫的結構體 /還是在msg中用分割符號得到更多的字段?

我覺得json可能會更好,因為我當初用的是分割符號,也就是在myshell中用來分割每乙個小段,比如id:1\nname:adl\nclass:計科1904\n通過乙個自己寫的函式去將這個片段根據分隔符』\n』分成三份,從而解析出我們需要的字段內容,然而我寫的函式需要在函式外開闢大量的陣列空間避免內容過長而導致的溢位,而且使用起來難以精確free。至於真要使用這種方法,分隔符請不要使用\n,因為這個過於常見,推薦使用"\r\n"。而如果使用結構體新增字段,你要知道,你傳送的包一般是固定的,但你如果需要傳送一些檔案的大小,名稱,你忽然發現你的結構體的字段不夠用,新增結構體欄位其實是一種下策(我就加了檔案的字段),因為伺服器和客戶端都會需要因此多維護很多相應的資訊。cjson呢你就可以比如想將乙個

發檔案如何讓對方知道我發完了呢?

傳送含end標誌位的包,end包的處理在聊天室中用到挺多的,顯示乙個好友列表,群列表。。。

重複加好友,**該怎麼處理???群主和管理員該怎麼同時處理這個請求???

這些重複需求大需要驗證該訊息已存在的操作。而群主和管理員只能讓乙個生效。

同時填寫乙個結構體的字段最好寫成函式

聊天記錄和其他型別的訊息需要在mysql中存放多久?(訊息的狀態flag)

時間戳這個其實挺重要的,這樣每次你傳送的訊息都可顯示時間,看上去炫酷多了!

寫聊天室的思路 先構思整體邏輯 再登入註冊入手 再實現私聊 再群聊(其實很多地方和私聊本質相同)

心態很容易**的,一次次痛苦的重構 ,唉,打不死你的只會讓你更強大!

mysql 聊天室 聊天室php mysql 六

聊天室php mysql 六 相應的 資料庫 phpmyadmin mysql dump 主機 localhost 3306 資料庫 study28 資料表的結構 chat user create table chat user userid varchar 20 not null,passwd v...

linux 聊天室 知識點

一 具體操作 1.登陸虛擬機器 ubutu 賬號 root 密碼root 2.開啟多個視窗 快捷鍵 ctrl alt t 3.開啟伺服器 server 4.設定本地ip位址 ifconfig eth0 192.168.1.1 檢視ip位址 ifcofig 將網絡卡禁用 ifconfig eth0 d...

聊天室程式

伺服器 include include include include include include include include define servport 8081 伺服器端口號 define bufsize 200 最大傳輸量 int main int args,char argv s...