国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

探討.NET網(wǎng)絡(luò)編程技術(shù)原理與開發(fā)實(shí)例

2014-10-23 06:26:34許懷民
科學(xué)時代·上半月 2014年9期
關(guān)鍵詞:技術(shù)原理開發(fā)

許懷民

【摘 要】.NET框架(.NET Framework) 是由微軟開發(fā),一個致力于敏捷軟件開發(fā)(Agile software development)、快速應(yīng)用開發(fā)(Rapid application development)、平臺無關(guān)性和網(wǎng)絡(luò)透明化的軟件開發(fā)平臺。.NET是微軟為下一個十年對服務(wù)器和桌面型軟件工程邁出的第一步。.NET包含許多有助于互聯(lián)網(wǎng)和內(nèi)部網(wǎng)應(yīng)用迅捷開發(fā)的技術(shù)。.NET框架是微軟公司繼Windows DNA之后的新開發(fā)平臺。.NET框架是以一種采用系統(tǒng)虛擬機(jī)運(yùn)行的編程平臺,以通用語言運(yùn)行庫(Common Language Runtime)為基礎(chǔ),支持多種語言(C#、VB.NET、C++、Python等)的開發(fā)。

【關(guān)鍵詞】.NET;技術(shù)原理;開發(fā)

本文簡述了.NET架構(gòu)中關(guān)于套接字、網(wǎng)絡(luò)編碼等底層網(wǎng)絡(luò)編程原理,詳細(xì)介紹.NET中socket中的異步套接字的方法。

一、基本原理

(一)套接字,套接字是網(wǎng)絡(luò)通信的基石,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元??梢詫ocket看作不同主機(jī)間的進(jìn)程進(jìn)行雙向通信的端點(diǎn),它構(gòu)成了單個主機(jī)內(nèi)及整個網(wǎng)絡(luò)間的編程界面。Socket存在于通信域(為了處理一般的線程通過Socket通信而引人的一種抽象概念)中。Socket通常和同一個域中的Socket交換數(shù)據(jù)。當(dāng)然,數(shù)據(jù)交換也可以穿越域的界限,但需要執(zhí)行某種特定的解釋程序。各種進(jìn)程在這個域中相互之間利用Internet協(xié)議簇來進(jìn)行通信。Socket有兩種不同的類型:流Socket和數(shù)據(jù)報Socket。應(yīng)用程序一般在同一類型Socket之間進(jìn)行通信。當(dāng)然,只要底層的通信協(xié)議允許,不同類型的Socket之間也可以通信。

(二)網(wǎng)絡(luò)編程, Socket不僅有阻塞與非阻塞之分,還允許同步或異步方式進(jìn)行操作。所謂同步方式,就是發(fā)送方發(fā)送數(shù)據(jù)分組之后,無需等待接收方響應(yīng),就接著發(fā)送下一個數(shù)據(jù)分組。異步方式是指當(dāng)發(fā)送方發(fā)送一個數(shù)據(jù)分組之后,一直等待接收方響應(yīng)后,才接著發(fā)送下一個數(shù)據(jù)分組。

(三)網(wǎng)絡(luò)流,在網(wǎng)絡(luò)通信中,流是一個用于傳輸數(shù)據(jù)的對象。數(shù)據(jù)傳輸有兩個方向:如果數(shù)據(jù)從外部源傳輸?shù)綉?yīng)用程序中,則為讀取流;如果數(shù)據(jù)從應(yīng)用程序傳輸?shù)酵獠吭粗?,即為寫人流。其中,外部源可以是文件、網(wǎng)絡(luò)、管道或內(nèi)存區(qū)域。流對外部數(shù)據(jù)源不做任何假設(shè)。通常,應(yīng)盡可能地使用一個獨(dú)立的對象來傳輸數(shù)據(jù),這樣可以將數(shù)據(jù)傳輸過程和數(shù)據(jù)源分離,更容易切換數(shù)據(jù)源。

(四)IP地址與DNS解析,System.Net空間提供了一些與網(wǎng)絡(luò)基本操作息息相關(guān)的類。比較重要的是IPAddress , Dns , IPHostEntry , IPEndEntry ,IPAddress類是一個描述IP地址的類。它的靜態(tài)方法Parse及TryParse可以將一個IP地址字符串實(shí)例化為一個IPAddress對象。Dns類是一個提供有關(guān)域名解析操作的靜態(tài)類。它將從網(wǎng)絡(luò)域名系統(tǒng)中獲取IP地址、主機(jī)名以及域名的對應(yīng)關(guān)系,并將這些信息保存在一個IPHostEntry對象中。IPHostEntrv的主要屬性成員有AddressList, Aliases和HostName分別保存主機(jī)的IP地址、別名和域名。IPEndPoint類表示一個連接端點(diǎn),即IP地址加上端口號構(gòu)成的一個綁定。

(五)網(wǎng)絡(luò)編碼與解碼,由于使用多種編程語言開發(fā)的應(yīng)用程序及多種支撐平臺在網(wǎng)絡(luò)這個混合體上運(yùn)行,并且網(wǎng)絡(luò)中有多種編碼方法:ASCII ,Unicode , UTF7 , UTFS , Big-Endian等,因此網(wǎng)絡(luò)編程中經(jīng)常要遇到編碼、解碼的操作。這種現(xiàn)狀需要一種將系統(tǒng)內(nèi)碼轉(zhuǎn)換成網(wǎng)絡(luò)編碼的機(jī)制,以便應(yīng)用程序能夠準(zhǔn)確地讀寫數(shù)據(jù)。.NET架構(gòu)的System.Text.Encoding類提供這種功能。

Encoding類提供了字符串、Unicode字符集和相應(yīng)編碼的字節(jié)數(shù)組之間的轉(zhuǎn)換(轉(zhuǎn)換的數(shù)據(jù)必須連續(xù))。事實(shí)上,應(yīng)用程序一般使用Encode:和Decode:來進(jìn)行轉(zhuǎn)換。Encoding類包含常用編碼的實(shí)例。開發(fā)者還可以在Encode:和Decoder的基礎(chǔ)上編寫自定義的編碼和解碼類來處理大量的數(shù)據(jù)轉(zhuǎn)換工作。

二、socket中的異步套接字的研究

(一)socket的建立

1. 構(gòu)造socket

不管是同步還是異步套接字,都必須首先建立起socket,這是后面連接的基礎(chǔ)。socket構(gòu)造函數(shù)如下:

public Socket (

AddressFamily addressFamily,

SocketType socketType,

ProtocolType protocolType

可以看到,里面有三個構(gòu)造函數(shù),每個參數(shù)其實(shí)都是一個枚舉值,第一個參數(shù)AddressFamily.InterNetwork說明我們采用IP 版本 4 的地址(現(xiàn)在都出版本6了);第二個參數(shù)SocketType.Stream是說建立的socket支持可靠、雙向、基于連接的字節(jié)流,而不重復(fù)數(shù)據(jù),也不保留邊界,此類型的 Socket 與單個對方主機(jī)進(jìn)行通信,并且在通信開始之前需要遠(yuǎn)程主機(jī)連接,Stream 使用傳輸控制協(xié)議 (Tcp) ProtocolType 和 InterNetworkAddressFamily。 第三個參數(shù)表名傳輸控制協(xié)議采用TCP。利用這三個參數(shù)就可以構(gòu)造一個socket實(shí)例。我們常用的構(gòu)造函數(shù)如下:

socket = new Socket(AddressFamily.InterNetwork, , ProtocolType.Tcp);

送信息至客戶端等等。

2.當(dāng)服務(wù)器端與客戶端的連接建立之后,就可以在兩方交流數(shù)據(jù)。但客戶端和服務(wù)器端的程序都會等待socket的動作,也就說在在socket發(fā)送或者接收數(shù)據(jù)過程中,兩方程序都會中止,一直等到發(fā)送或者接收數(shù)據(jù)完畢才會繼續(xù)往下執(zhí)行。這種情況下,最明顯的表現(xiàn)就是:如果是winForm程序,窗口會表現(xiàn)出死機(jī)狀態(tài),該狀態(tài)到程序往下繼續(xù)執(zhí)行的時候才會恢復(fù)。

(二)異步套接字

在同步里面,當(dāng)接收或者發(fā)送數(shù)據(jù)的時候,程序的進(jìn)程是中止的,一直在等待,那么想要解決這個問題自然就會想到——接收或者發(fā)送數(shù)據(jù)的時候程序繼續(xù)往下執(zhí)行就行了。 但是這樣問題就來了:接受或者發(fā)送數(shù)據(jù)完畢之后本來是想執(zhí)行一些針對這些數(shù)據(jù)或者另外相關(guān)的操作,現(xiàn)在不理會數(shù)據(jù)的接受或者發(fā)送的話,那我的這些想要的操作怎么去執(zhí)行?這個問題是這樣解決的:在該操作發(fā)生前定義該操作為之后的特定操作,服務(wù)器端希望在接收完客戶端發(fā)送的數(shù)據(jù)后再將該數(shù)據(jù)發(fā)送回給客戶端。那么,在這里我們就可以將把接收的數(shù)據(jù)發(fā)送回給客戶端作為一個操作,程序里面自然就是一個函數(shù)了,將這個函數(shù)定義為服務(wù)器端接收完數(shù)據(jù)之后立即執(zhí)行的函數(shù)。

服務(wù)器端代碼:

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

public class StateObject {

public Socket workSocket = null;

public const int BufferSize = 1024;

public byte[] buffer = new byte[BufferSize];

public StringBuilder sb = new StringBuilder();

}

public class AsynchronousSocketListener {

public static ManualResetEvent allDone = new ManualResetEvent(false);

public AsynchronousSocketListener() {

}

public static void StartListening() {

byte[] bytes = new Byte[1024];

IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());

IPAddress ipAddress = ipHostInfo.AddressList[0];

IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

Socket listener = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp );

try {

listener.Bind(localEndPoint);

listener.Listen(100);

while (true) {

allDone.Reset();

Console.WriteLine("Waiting for a connection...");

listener.BeginAccept(

new AsyncCallback(AcceptCallback),

listener );

allDone.WaitOne();

}

} catch (Exception e) {

Console.WriteLine(e.ToString());

}

Console.WriteLine("\nPress ENTER to continue...");

Console.Read();

}

public static void AcceptCallback(IAsyncResult ar) {

allDone.Set();

Socket listener = (Socket) ar.AsyncState;

Socket handler = listener.EndAccept(ar);

StateObject state = new StateObject();

state.workSocket = handler;

handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,

new AsyncCallback(ReadCallback), state);

}

public static void ReadCallback(IAsyncResult ar) {

String content = String.Empty;

StateObject state = (StateObject) ar.AsyncState;

Socket handler = state.workSocket;

int bytesRead = handler.EndReceive(ar);

if (bytesRead > 0) {

state.sb.Append(Encoding.ASCII.GetString(

state.buffer,0,bytesRead));

content = state.sb.ToString();

if (content.IndexOf("") > -1) {

Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",

content.Length, content );

Send(handler, content);

} else {

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,

new AsyncCallback(ReadCallback), state);

}

}

}

private static void Send(Socket handler, String data) {

byte[] byteData = Encoding.ASCII.GetBytes(data);

handler.BeginSend(byteData, 0, byteData.Length, 0,

new AsyncCallback(SendCallback), handler);

}

private static void SendCallback(IAsyncResult ar) {

try {

Socket handler = (Socket) ar.AsyncState;

int bytesSent = handler.EndSend(ar);

Console.WriteLine("Sent {0} bytes to client.", bytesSent);

handler.Shutdown(SocketShutdown.Both);

handler.Close();

} catch (Exception e) {

Console.WriteLine(e.ToString());

}

}

public static int Main(String[] args) {

StartListening();

return 0;

}

}

客戶端代碼:

public class AsynchronousClient {

private const int port = 11000;

private static ManualResetEvent connectDone =

new ManualResetEvent(false);

private static ManualResetEvent sendDone =

new ManualResetEvent(false);

private static ManualResetEvent receiveDone =

new ManualResetEvent(false);

private static String response = String.Empty;

private static void StartClient() {

try {

IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");

IPAddress ipAddress = ipHostInfo.AddressList[0];

IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

Socket client = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp);

client.BeginConnect( remoteEP,

new AsyncCallback(ConnectCallback), client);

connectDone.WaitOne();

Send(client,"This is a test");

sendDone.WaitOne();

Receive(client);

receiveDone.WaitOne();

Console.WriteLine("Response received : {0}", response);

client.Shutdown(SocketShutdown.Both);

client.Close();

} catch (Exception e) {

Console.WriteLine(e.ToString());

}

}

private static void ConnectCallback(IAsyncResult ar) {

try {

Socket client = (Socket) ar.AsyncState;

client.EndConnect(ar);

Console.WriteLine("Socket connected to {0}",

client.RemoteEndPoint.ToString());

connectDone.Set();

} catch (Exception e) {

Console.WriteLine(e.ToString());

}

}

private static void Receive(Socket client) {

try {

StateObject state = new StateObject();

state.workSocket = client;

client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,

new AsyncCallback(ReceiveCallback), state);

} catch (Exception e) {

Console.WriteLine(e.ToString());

}

}

private static void ReceiveCallback( IAsyncResult ar ) {

try {

StateObject state = (StateObject) ar.AsyncState;

Socket client = state.workSocket;

int bytesRead = client.EndReceive(ar);

if (bytesRead > 0) {

state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));

client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,

new AsyncCallback(ReceiveCallback), state);

} else {

if (state.sb.Length > 1) {

response = state.sb.ToString();

}

receiveDone.Set();

}

} catch (Exception e) {

Console.WriteLine(e.ToString());

}

}

private static void Send(Socket client, String data) {

byte[] byteData = Encoding.ASCII.GetBytes(data);

client.BeginSend(byteData, 0, byteData.Length, 0,

new AsyncCallback(SendCallback), client);

}

private static void SendCallback(IAsyncResult ar) {

try {

Socket client = (Socket) ar.AsyncState;

int bytesSent = client.EndSend(ar);

Console.WriteLine("Sent {0} bytes to server.", bytesSent);

sendDone.Set();

} catch (Exception e) {

Console.WriteLine(e.ToString());

}

}

public static int Main(String[] args) {

StartClient();

return 0;

}

}

三、結(jié)束語

任何技術(shù)的核心并不難,難就難在當(dāng)該技術(shù)發(fā)展成熟以后為了各種需要而添加的枝枝蔓蔓,這些后期添加的東西一方面使技術(shù)的應(yīng)用更加方便和穩(wěn)定,另一方面,對于學(xué)習(xí)該技術(shù)的人來說,增加了不少的學(xué)習(xí)成本和障礙。學(xué)習(xí)技術(shù)的理念就是,將其枝枝蔓蔓的不斷裁剪,一直到露出問題的最最核心,然后掌握這個核心,之后從該核心出發(fā),順著問題的發(fā)展思路去學(xué)習(xí),一切就是理所當(dāng)然了。

猜你喜歡
技術(shù)原理開發(fā)
淺談智能化除草機(jī)器人技術(shù)發(fā)展現(xiàn)狀及趨勢展望
河南方言文化資源的保護(hù)及其開發(fā)利用的研究
遵義紅色旅游開發(fā)對策研究
基于J2EE和Ionic的ITer學(xué)習(xí)APP設(shè)計(jì)與開發(fā)
單片機(jī)在電子技術(shù)中的應(yīng)用和開發(fā)
COFDM在現(xiàn)代數(shù)字廣播DRM中的應(yīng)用
科技視界(2016年11期)2016-05-23 10:05:17
基于VPN的計(jì)算機(jī)虛擬網(wǎng)絡(luò)技術(shù)及應(yīng)用
葫芦岛市| 凤山县| 茶陵县| 重庆市| 宜宾县| 安溪县| 潮州市| 社旗县| 温州市| 惠水县| 宜兴市| 赤水市| 叶城县| 五莲县| 云林县| 涞源县| 湖北省| 天全县| 察雅县| 互助| 宕昌县| 金塔县| 双桥区| 凤凰县| 竹溪县| 广州市| 孟连| 双流县| 河曲县| 永川市| 大城县| 卢氏县| 嘉荫县| 永宁县| 周宁县| 镇雄县| 绥江县| 榆林市| 荣昌县| 桓台县| 邵武市|