學習網路編程,想寫個聊天伺服器練練,想實現客戶端之間的通信,但是卡殼了?

設計是這樣的

1,客戶端一旦連接到伺服器,就發送自己用戶id(先不弄登錄功能),

伺服器收到後將用戶id與連接套接字fd對應起來放到map.

2,然後伺服器再接收客戶端放送過來的消息包,結構是{放送者id,msg,接受者id}

根據接收者id向map中對應套接字發送msg.

問題是如何保證伺服器先執行第一步中接收用戶id的消息,然後再接受實際消息。

保證伺服器能在map中找到對應套接字?

–––

我還是滾回去好好看書打好基礎再實踐了


先好好看一下socket基礎,找一些參考實現,別瞎弄
客戶端和server通信依靠協議(protocol),protocol一般表示為狀態機,從連接建立是第一個狀態,連接銷毀是最後一個,也有按session的。兩端尤其是server應該有完整的正常和異常情況的處理,一般出現異常就立即清理資源銷毀連接就行。
先畫下狀態圖,然後照著別人的模子動手寫,自己測,別老空想了。


首先,你要說清楚你現在用的是 TCP 還是 UDP。

  • 如果是 TCP,那麼伺服器不可能先收到第二條消息。
  • 如果是 UDP,請換成 TCP。

再說清楚你的伺服器採用的是哪種並發IO模型,如果是 thread-per-connection,那它不可能先收到第二條消息,如果是單線程 reactor,那也不可能先收到第二條消息。那你就究竟用的是哪種IO模型?


推薦一款簡單明了易學易用的輕量級開源即時通訊軟體flamingo:
https://github.com/baloonwj/flamingo


我寫過一個,心跳是用TCP,看他在不在線的,傳輸信息是用UDP,傳送的結構比你這個複雜一些,語音和圖片轉換成二進位傳輸,視頻的原理和用的是Html5裡面的協議(電腦上),手機端直接用了現成的框架,有點複雜.....我一兩句說不清,等我有空給你詳細的打出來,建議看看環信的框架,或者你著急直接集成他都行


1. 你的思路還是比較正確的,但是需要用到TCP協議,這樣必然是建立連接後才接受消息.後面建立一個Map將ID和Socket進行一對一的映射;後面消息處理過程也沒有什麼大問題.
2.如果是UDP,那麼也有辦法,只是說差不多要實現TCP那樣的過程.

-------------------------分割線-以下回答作廢-------------------------
2.我認為你不需要考慮接收方在線才允許發送消息,而是說考慮接收方不在線怎麼處理,將消息緩存還是說直接丟棄。
3.如果要做到接收方不在線就無法發送消息的話,可以在發消息之前客戶端與伺服器做一次驗證,看接收方是否在線,不在線就不允許發送. 或者,任何客戶端上線、下線都通知到其它客戶端,讓其它客戶端自己判斷.


清晰易懂TCP通信原理解析(附demo、簡易TCP通信庫源碼、解決沾包問題等)C#版 - 周見智 - 博客園

tcp/udp/socket 詳細教程


建議使用現成的網路庫,比如C#的supersocket,能熟練的使用之後再開始用原生socket來寫


1 伺服器主線程接受請求,子線程與客戶端通信
2 map中將客戶端的ID和Socket進行映射
3 確定map中有客戶端id再接收後續消息


正在寫一個聊天室小應用。

保證伺服器收到客戶端ID,可以在客戶端代碼里加一條請求輸入,用戶輸入一個臨時名字,把這個名字當中ID,然後發送到伺服器。

伺服器將這個名字跟socket連接放在一個map里就好了。


維護一個在線用戶表啊,然後收到實際消息,先看接受者有沒有在線,在線再去找對應的fd發送。。不知道有沒有理解錯


主線程不斷接收來自客戶端的連接,並有子線程服務客戶端。
共享數據保存客戶端的連接數據。注意數據同步的問題。


推薦閱讀:

1.1.1.1 是哪裡的 IP?
為什麼TCP的MSS協商沒有按照小的來?
關於IP數據報轉發的疑問?
個人計算機裡面包含網路7層協議的所有協議嗎,每一層分別對應哪個部分?
交換機mac表的獲取?

TAG:Linux開發 | 網路編程 | TCPIP | 服務端開發 |