使用SOCKET實現TCP IP協議的通訊

2021-09-30 10:26:35 字數 4426 閱讀 3823

一、原理:

在上面這張圖中,你可以理解為程式a和程式b是2個socket程式,伺服器端程式a設定埠為81,已接受到3個客戶端的連線,計算機c開了2個程式,分別連線到e和d,而他的埠是計算機自動分配的,連線到e的埠為789,連線到d的為790。

了解了tcpip通訊的基本結構後,接下來講解建立的流程,首先宣告一下我用的開發環境是visual studio2008版的,語言c#,元件system.net.sockets,流程的建立包括伺服器端的建立和客戶端的建立,如圖所示:

二、實現:

1.客戶端:

第一步,要建立乙個客戶端物件tcpclient(命名空間在system.net.sockets),接著,呼叫物件下的方法beginconnect進行嘗試連線,入口引數有4個,address(目標ip位址),port(目標埠號),requestcallback(連線成功後的返調函式),state(傳遞引數,是乙個物件,隨便什麼都行,我建議是將tcpclient自己傳遞過去),呼叫完畢這個函式,系統將進行嘗試連線伺服器。

第二步,在第一步講過乙個入口引數requestcallback(連線成功後的返調函式),比如我們定義乙個函式void connected(iasyncresult result),在連線伺服器成功後,系統會呼叫此函式,在函式裡,我們要獲取到系統分配的資料流傳輸物件(networkstream),這個物件是用來處理客戶端與伺服器端資料傳輸的,此物件由tcpclient獲得,在第一步講過入口引數state,如果我們傳遞了tcpclient進去,那麼,在函式裡我們可以根據入口引數state獲得,將其進行強制轉換tcpclient tcpclt = (tcpclient)result.asyncstate,接著獲取資料流傳輸物件networkstream ns = tcpclt.getstream(),此物件我建議弄成全域性變數,以便於其他函式呼叫,接著我們將掛起資料接收等待,呼叫ns下的方法beginread,入口引數有5個,buff(資料緩衝),offset(緩衝起始序號),size(緩衝長度),callback(接收到資料後的返調函式),state(傳遞引數,一樣,隨便什麼都可以,建議將buff傳遞過去),呼叫完畢函式後,就可以進行資料接收等待了,在這裡因為已經建立了networkstream物件,所以也可以進行向伺服器傳送資料的操作了,呼叫ns下的方法write就可以向伺服器傳送資料了,入口引數3個,buff(資料緩衝),offset(緩衝起始序號),size(緩衝長度)。

第三步,在第二步講過呼叫了beginread函式時的乙個入口引數callback(接收到資料後的返調函式),比如我們定義了乙個函式void datarec(iasyncresult result),在伺服器向客戶端傳送資料後,系統會呼叫此函式,在函式裡我們要獲得資料流(byte陣列),在上一步講解beginread函式的時候還有乙個入口引數state,如果我們傳遞了buff進去,那麼,在這裡我們要強制轉換成byte型別byte data= (byte)result.asyncstate,轉換完畢後,我們還要獲取緩衝區的大小int length = ns.endread(result),ns為上一步建立的networkstream全域性物件,接著我們就可以對資料進行處理了,如果獲取的length為0表示客戶端已經斷開連線。

具體實現**,在這裡我建立了乙個名稱為test的類:

usingsystem;

using system.collections.generic;

using system.net.sockets;

namespace test

/// /// 傳送資料

///

/// 資料

public void senddata(byte data)

/// /// 關閉

///

public void close()

/// /// 關閉

///

/// 傳入引數

protected void connected(iasyncresult result)

/// /// 資料接收委託函式

///

/// 傳入引數

protected void datarec(iasyncresult result)}}

}

2.伺服器端:

相對於客戶端的實現,伺服器端的實現稍複雜一點,因為前面講過,乙個伺服器端可以接受n個客戶端的連線,因此,在伺服器端,有必要對每個連線上來的客戶端進行登記,因此伺服器端的程式結構包括了2個程式結構,第乙個程式結構主要負責啟動伺服器、對來訪的客戶端進行登記和撤銷,因此我們需要建立2個類。

第乙個程式結構負責伺服器的啟動與客戶端連線的登記,首先建立tcplistener網路偵聽類,建立的時候建構函式分別包括localaddr和port2個引數,localaddr指的是本地位址,也就是伺服器的ip位址,有人會問為什麼它自己不去自動獲得本機的位址?關於這個舉個很簡單的例子,伺服器安裝了2個網絡卡,也就有了2個ip位址,那建立伺服器的時候就可以選擇偵聽的使用的是哪個網路埠了,不過一般的電腦只有乙個網路埠,你可以懶點直接寫個固定的函式直接獲取ip位址system.net.dns.gethostaddresses(system.net.dns.gethostname())[0],gethostaddresses函式就是獲取本機的ip位址,預設選擇第乙個埠於是後面加個[0],第2個引數port是真偵聽的埠,這個簡單,自己決定,如果出現埠衝突,函式自己會提醒錯誤的。第二步,啟動伺服器,tcplistener.start()。第三步,啟動客戶端的嘗試連線,tcplistener.beginaccepttcpclient,入口2個引數,callback(客戶端連線上後的返調函式),state(傳遞引數,跟第二節介紹的一樣,隨便什麼都可以,建立把tcplistener自身傳遞過去),第四步,建立客戶端連線上來後的返調函式,比如我們建立個名為void clientaccept(iasyncresult result)的函式,函式裡,我們要獲取客戶端的物件,第三步裡講過我們傳遞tcplistener引數進去,在這裡,我們通過入口引數獲取它tcplistener tcplst = (tcplistener)result.asyncstate,獲取客戶端物件tcpclient bak_tcpclient = tcplst.endaccepttcpclient(result),這個bak_tcpclient我建議在類裡面建立個列表,然後把它加進去,因為下乙個客戶端連線上來後此物件就會被沖刷掉了,客戶端處理完畢後,接下來我們要啟動下乙個客戶端的連線tcplst.beginaccepttcpclient(new asynccallback(sub_clientaccept), tcplst),這個和第三步是一樣的,我就不重複了。

第二個程式結構主要負責單個客戶端與伺服器端的處理程式,主要負責資料的通訊,方法很類似客戶端的**,基本大同,除了不需要啟動連線的函式,因此這個程式結構主要啟動下資料的偵聽的功能、判斷斷開的功能、資料傳送的功能即可,在第乙個程式第四步我們獲取了客戶端的物件bak_tcpclient,在這裡,我們首先啟動資料偵聽功能networkstream ns= bak_tcpclient.getstream();ns.beginread(data, 0, 1024, new asynccallback(datarec), data);這個跟我在第二節裡介紹的是一模一樣的(第二節第10行),還有資料的處理函式,資料傳送函式,判斷連線已斷開的**與第二節也是一模一樣的,不過在這裡我們需要額外的新增一段**,當判斷出連線已斷開的時候,我們要將客戶端告知第乙個程式結構進行刪除客戶端操作,這個方法我的實現方法是在建立第二個程式結構的時候,將第乙個程式結構當引數傳遞進來,判斷連線斷開後,呼叫第乙個程式結構的公開方法去刪除,即從客戶端列表下刪除此物件。

第乙個程式結構我們定義乙個tsever的類,第二個程式結構我們乙個tclient的類,**如下:

public class tsever

private void clientaccept(iasyncresult result)

} public class tclient

/// /// 資料接收

///

///

private void datarec(iasyncresult result)

else

}/// /// 傳送資料

///

/// 資料

///

public bool senddata(byte data)

}

摘自:

大話 詳解TCP IP及C 實現 Socket

1.先來個在excel編寫的 自己編寫的內容 主要解釋一下客戶端與服務端之間的三次握手連線和四次揮手斷開。繫結ip 和埠 public server bind string ip,int port 開始監聽 public server listen int queuecount 非同步傳輸資料 這裡...

TCP IP以及socket原理

tcp ip協議族,tcp ip transmission control protocol internet protocol 即傳輸控制協議 網間協議,定義了主機如何連入網際網路及資料如何再它們之間傳輸的標準,從字面意思來看tcp ip是tcp和ip協議的合稱,但實際上tcp ip協議是指網際網...

tcp ip 網路程式設計 socket

一 使用tcp協議實現client向server傳送資料 tcp程式設計例一 客戶端給服務端傳送資訊。服務端輸出此資訊到控制台上 網路程式設計實際上就是socket的程式設計 public class testtcp1 catch ioexception e finally catch ioexce...