基於TCP的網路遊戲黑白棋系列(一) 建立連線

2021-09-05 19:41:47 字數 2579 閱讀 9020

利用tcp開發網路應用程式,可以採用同步或者非同步的方式,這個遊戲採用的是同步的工作方式,比較簡單,系列教程也主要介紹同步的工作方式。

網路通訊的前提就是客戶端和伺服器端的通訊,在伺服器端,程式需要不斷的監聽客戶端是否有連線請求,已保證多個客戶端的連線,伺服器通過套接字識別客戶端;而客戶端只需要指定哪個伺服器即可。一旦雙方建立連線並建立了對應的套接字,就可以互相傳輸資料了。客戶端和伺服器端傳送和接受資料的方法都是一樣的,區別僅是方向不同。

在同步tcp網路應用程式中,傳送、接受和監聽語句均採用阻塞方式工作,一般有如下步驟:

(1)建立乙個包含所採用的網路型別、資料傳輸型別和協議型別的本地套接字物件,並將其餘伺服器的ip位址和埠號繫結。可通過socket類或者tcplistener類完成。

(2)在指定的埠進行監聽,以便接受客戶端的連線請求。

(3)一旦接受了客戶端的連線請求,就根據客戶端傳送的連線資訊建立與該客戶端對應的socket物件或者tcpclient物件。

(4)根據建立的socket物件或者tcpclient物件,分別與每個連線的客戶進行資料傳輸。

(5)根據傳送資訊的情況確定是否關閉與對方的連線。

本文的目的是完成前三步,即建立伺服器和客戶端的連線,伺服器將根據對應客戶端建立的tcpclient物件得到客戶端的資訊

伺服器端部分**

ipaddress localaddress;

intport 

=51888

;tcplistener mylistener;

service service 

=new

service(listbox);

ipaddress addrip 

=dns.gethostaddresses(dns.gethostname());

localaddress 

=addrip[0];

mylistener 

=new

tcplistener(localaddress, port);

mylistener.start();

service.setlistbox(

string

.format(

"開始在:監聽客戶連線

", localaddress, port));

threadstart ts 

=new

threadstart(listenclientconnect);

thread mythread 

=new

thread(ts);

mythread.start();

我們可以看到建立了乙個tcplistener,並且呼叫了tcplistener.start();接著啟動了乙個執行緒,迴圈的接受客戶端的請求並建立對應的tcpclient物件,看一下listenclientconnect方法

while

(true

)catch

user user 

=new

user(newclient);

userlist.add(user);

service.setlistbox(

string

.format("進入

", newclient.client.remoteendpoint));

service.setlistbox(

string

.format(

"當前連線使用者數:

",userlist.count));}

其中的while(true)用法看起來比較奇怪,但沒什麼問題,保證應答多個客戶端的請求。

客戶端的**

tcpclient client 

=null

;try

catch

客戶端**很簡單,因為不需要傳輸資料,這樣當伺服器端監聽到請求後,利用建立的tcpclient物件的到該客戶端的資訊,通過呼叫service.setlistbox列印到listbox中(在遊戲中每個視窗都有乙個listbox,使大家看到伺服器和客戶端互動的一些資訊,方便除錯)

service**

class

service

public

void

setlistbox(

string

str)

else}}

大家一定會對setlistbox的寫法比較奇怪,這裡實際上是多執行緒中呼叫winform 的方法,來看網上的一段話

每乙個從control類中派生出來的winform類(包括control類)都是依靠底層windows訊息和乙個訊息幫浦迴圈(message pump loop)來執行的。訊息迴圈都必須有乙個相對應的執行緒。由於最初訊息迴圈的緣故,只有建立該form的執行緒才能呼叫其事件處理方法。

換句話說,如果你在你自己的執行緒中呼叫這些方法,則它們會在該執行緒中處理事件,而不是在建立該form的主線程中進行處理,這時就需要通過control.invoke方法返回窗體主線程執行相關操作。

同時,由於程式中大量使用了setlistbox方法,因此將其修改為自動判斷是否需要invoke,而使用該方法時不需要關心此細節。invoke的第乙個引數是乙個setlistboxcallback委託,此處也可以用匿名函式實現,**更簡潔。

基於TCP的網路遊戲黑白棋系列教程開篇

看過網上很多的類似系列教程 包包版網路大廳的 橋牌系統 寫的很深入,感覺比較複雜,初學者不宜上手。我是在學習wcf的時候,發現自己對底層的傳輸原理都沒有搞明白,於是又回頭學習網路傳輸的一些知識,自己寫了乙個簡單的網路遊戲黑白棋,因此也想把學習的乙個過程記錄下來和初學者們一塊交流。我的只是小兒科,還請...

基於TCP的網路遊戲黑白棋系列(三) 遊戲大廳

上一節我們講到了客戶端傳送login命令後,伺服器返回歡迎資訊,完成了乙個簡單的資料傳輸。這一節我們來完成遊戲大廳的基本功能,我們首先思考一下遊戲大廳的基本功能 1 提供可供對弈的遊戲桌,遊戲大廳可供多桌玩家同時遊戲,為了考慮遊戲大廳伺服器的負載能力,應該設定乙個人數的上限和桌數的上限。實際上前面提...

基於SDL的C 黑白棋

寫了乙個基於sdl的黑白棋遊戲,分享一下。黑白棋,又叫翻轉棋 reversi 奧賽羅棋 othello 蘋果棋或反棋 anti reversi 黑白棋在西方和日本很流行。遊戲通過相互翻轉對方的棋子,最後以棋盤上誰的棋子多來判斷勝負。如果玩家在棋盤上沒有地方可以下子,則該玩家對手可以連下。雙方都沒有棋...