資源簡介
首先要理解基本的原理,2臺電腦間實(shí)現(xiàn)TCP通訊,首先要建立起連接,在這里要提到服務(wù)器端與客戶端,兩個的區(qū)別通俗講就是主動與被動的關(guān)系,兩個人對話,肯定是先有人先發(fā)起會話,要不然誰都不講,談什么話題,呵呵!一樣,TCPIP下建立連接首先要有一個服務(wù)器,它是被動的,它只能等待別人跟它建立連接,自己不會去主動連接,那客戶端如何去連接它呢,這里提到2個東西,IP地址和端口號,通俗來講就是你去拜訪某人,知道了他的地址是一號大街2號樓,這個是IP地址,那么1號樓這么多門牌號怎么區(qū)分,嗯!門牌號就是端口(這里提到一點(diǎn),我們訪問網(wǎng)頁的時候也是IP地址和端口號,IE默認(rèn)的端口號是80),一個服務(wù)器可以接受多個客戶端的連接,但是一個客戶端只能連接一臺服務(wù)器,在連接后,服務(wù)器自動劃分內(nèi)存區(qū)域以分配各個客戶端的通訊,那么,那么多的客戶端服務(wù)器如何區(qū)分,你可能會說,根據(jù)IP么,不是很完整,很簡單的例子,你一臺計算機(jī)開3個QQ,服務(wù)器怎么區(qū)分?所以準(zhǔn)確的說是IP和端口號,但是客戶端的端口號不是由你自己定的,是由計算機(jī)自動分配的,要不然就出現(xiàn)端口沖突了,說的這么多,看下面的這張圖就簡單明了了。
在上面這張圖中,你可以理解為程序A和程序B是2個SOCKET程序,服務(wù)器端程序A設(shè)置端口為81,已接受到3個客戶端的連接,計算機(jī)C開了2個程序,分別連接到E和D,而他的端口是計算機(jī)自動分配的,連接到E的端口為789,連接到D的為790。
了解了TCPIP通訊的基本結(jié)構(gòu)后,接下來講解建立的流程,首先聲明一下我用的開發(fā)環(huán)境是Visual Studio2008版的,語言C#,組件System.Net.Sockets,流程的建立包括服務(wù)器端的建立和客戶端的建立,如圖所示:
二、實(shí)現(xiàn):
1.客戶端:
第一步,要創(chuàng)建一個客戶端對象TcpClient(命名空間在System.Net.Sockets),接著,調(diào)用對象下的方法BeginConnect進(jìn)行嘗試連接,入口參數(shù)有4個,address(目標(biāo)IP地址),port(目標(biāo)端口號),requestCallback(連接成功后的返調(diào)函數(shù)),state(傳遞參數(shù),是一個對象,隨便什么都行,我建議是將TcpClient自己傳遞過去),調(diào)用完畢這個函數(shù),系統(tǒng)將進(jìn)行嘗試連接服務(wù)器。
第二步,在第一步講過一個入口參數(shù)requestCallback(連接成功后的返調(diào)函數(shù)),比如我們定義一個函數(shù)void Connected(IAsyncResult result),在連接服務(wù)器成功后,系統(tǒng)會調(diào)用此函數(shù),在函數(shù)里,我們要獲取到系統(tǒng)分配的數(shù)據(jù)流傳輸對象(NetworkStream),這個對象是用來處理客戶端與服務(wù)器端數(shù)據(jù)傳輸?shù)模藢ο笥蒚cpClient獲得,在第一步講過入口參數(shù)state,如果我們傳遞了TcpClient進(jìn)去,那么,在函數(shù)里我們可以根據(jù)入口參數(shù)state獲得,將其進(jìn)行強(qiáng)制轉(zhuǎn)換TcpClient tcpclt = (TcpClient)result.AsyncState,接著獲取數(shù)據(jù)流傳輸對象NetworkStream ns = tcpclt.GetStream(),此對象我建議弄成全局變量,以便于其他函數(shù)調(diào)用,接著我們將掛起數(shù)據(jù)接收等待,調(diào)用ns下的方法BeginRead,入口參數(shù)有5個,buff(數(shù)據(jù)緩沖),offset(緩沖起始序號),size(緩沖長度),callback(接收到數(shù)據(jù)后的返調(diào)函數(shù)),state(傳遞參數(shù),一樣,隨便什么都可以,建議將buff傳遞過去),調(diào)用完畢函數(shù)后,就可以進(jìn)行數(shù)據(jù)接收等待了,在這里因為已經(jīng)創(chuàng)建了NetworkStream對象,所以也可以進(jìn)行向服務(wù)器發(fā)送數(shù)據(jù)的操作了,調(diào)用ns下的方法Write就可以向服務(wù)器發(fā)送數(shù)據(jù)了,入口參數(shù)3個,buff(數(shù)據(jù)緩沖),offset(緩沖起始序號),size(緩沖長度)。
第三步,在第二步講過調(diào)用了BeginRead函數(shù)時的一個入口參數(shù)callback(接收到數(shù)據(jù)后的返調(diào)函數(shù)),比如我們定義了一個函數(shù)void DataRec(IAsyncResult result),在服務(wù)器向客戶端發(fā)送數(shù)據(jù)后,系統(tǒng)會調(diào)用此函數(shù),在函數(shù)里我們要獲得數(shù)據(jù)流(byte數(shù)組),在上一步講解BeginRead函數(shù)的時候還有一個入口參數(shù)state,如果我們傳遞了buff進(jìn)去,那么,在這里我們要強(qiáng)制轉(zhuǎn)換成byte[]類型byte[] data= (byte[])result.AsyncState,轉(zhuǎn)換完畢后,我們還要獲取緩沖區(qū)的大小int length = ns.EndRead(result),ns為上一步創(chuàng)建的NetworkStream全局對象,接著我們就可以對數(shù)據(jù)進(jìn)行處理了,如果獲取的length為0表示客戶

代碼片段和文件信息
using?System;
using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
using?System.Threading.Tasks;
namespace?Sever
{
????class?Program
????{
????????static?void?Main(string[]?args)
????????{
????????????TSever?tServer?=?new?TSever(9001);
????????????Console.ReadLine();
????????}
????}
}
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????目錄???????????0??2018-05-13?22:58??TcpIpDemo\
?????目錄???????????0??2018-05-13?22:58??TcpIpDemo\.vs\
?????目錄???????????0??2018-05-13?22:58??TcpIpDemo\.vs\TcpIpDemo\
?????目錄???????????0??2018-05-13?22:58??TcpIpDemo\.vs\TcpIpDemo\v15\
?????文件???????92672??2018-05-20?14:39??TcpIpDemo\.vs\TcpIpDemo\v15\.suo
?????目錄???????????0??2018-05-13?22:58??TcpIpDemo\.vs\TcpIpDemo\v15\Server\
?????目錄???????????0??2018-05-20?14:39??TcpIpDemo\.vs\TcpIpDemo\v15\Server\sqlite3\
?????文件???????????0??2018-05-13?22:58??TcpIpDemo\.vs\TcpIpDemo\v15\Server\sqlite3\db.lock
?????文件??????581632??2018-05-13?23:49??TcpIpDemo\.vs\TcpIpDemo\v15\Server\sqlite3\storage.ide
?????目錄???????????0??2018-05-13?23:35??TcpIpDemo\Server\
?????文件?????????189??2018-04-21?10:22??TcpIpDemo\Server\App.config
?????文件?????????326??2018-04-21?10:31??TcpIpDemo\Server\Program.cs
?????目錄???????????0??2018-05-13?21:49??TcpIpDemo\Server\Properties\
?????文件????????1336??2018-04-21?10:22??TcpIpDemo\Server\Properties\AssemblyInfo.cs
?????文件????????2733??2018-04-21?12:31??TcpIpDemo\Server\Server.csproj
?????文件????????3737??2018-05-13?23:35??TcpIpDemo\Server\TServer.cs
?????目錄???????????0??2018-05-13?21:49??TcpIpDemo\Server\bin\
?????目錄???????????0??2018-05-13?23:41??TcpIpDemo\Server\bin\Debug\
?????文件????????7168??2018-05-13?23:41??TcpIpDemo\Server\bin\Debug\Server.exe
?????文件?????????189??2018-04-21?10:22??TcpIpDemo\Server\bin\Debug\Server.exe.config
?????文件???????15872??2018-05-13?23:41??TcpIpDemo\Server\bin\Debug\Server.pdb
?????文件???????23168??2018-05-11?09:24??TcpIpDemo\Server\bin\Debug\Server.vshost.exe
?????文件?????????189??2018-04-21?10:22??TcpIpDemo\Server\bin\Debug\Server.vshost.exe.config
?????文件?????????490??2015-07-10?19:01??TcpIpDemo\Server\bin\Debug\Server.vshost.exe.manifest
?????目錄???????????0??2018-05-13?21:49??TcpIpDemo\Server\obj\
?????目錄???????????0??2018-05-13?23:41??TcpIpDemo\Server\obj\Debug\
?????文件????????6690??2018-05-13?23:41??TcpIpDemo\Server\obj\Debug\DesignTimeResolveAssemblyReferencesInput.cache
?????文件??????????42??2018-05-13?23:41??TcpIpDemo\Server\obj\Debug\Server.csproj.CoreCompileInputs.cache
?????文件?????????905??2018-05-13?23:41??TcpIpDemo\Server\obj\Debug\Server.csproj.FileListAbsolute.txt
?????文件????????9132??2018-05-13?23:41??TcpIpDemo\Server\obj\Debug\Server.csprojResolveAssemblyReference.cache
?????文件????????7168??2018-05-13?23:41??TcpIpDemo\Server\obj\Debug\Server.exe
............此處省略73個文件信息
評論
共有 條評論