非同步伺服器套接字使用 .net framework 非同步程式設計模型處理網路服務請求。socket 類遵循標準 .net framework 非同步命名模式;例如,同步 accept 方法對應非同步 beginaccept 和 endaccept 方法。
非同步伺服器套接字需要乙個開始接受網路連線請求的方法,乙個處理連線請求並開始接收網路資料的**方法以及乙個結束接收資料的**方法。本節將進一步討論所有這些方法。
在下面的示例中,為開始接受網路連線請求,方法 startlistening 初始化 socket,然後使用 beginaccept 方法開始接受新連線。當套接字上接收到新連線請求時,將呼叫接受**方法。它負責獲取將處理連線的 socket 例項,並將 socket 提交給將處理請求的執行緒。接受**方法實現 asynccallback 委託;它返回 void,並帶乙個 iasyncresult 型別的引數。下面的示例是接受**方法的外殼程式。
[visual basic]
sub acceptcallback(ar as iasyncresult)
' add the callback code here.
end sub 'acceptcallback
[c#]
void acceptcallback( iasyncresult ar)
beginaccept 方法帶兩個引數:指向接受**方法的 asynccallback 委託和乙個用於將狀態資訊傳遞給**方法的物件。在下面的示例中,偵聽 socket 通過狀態引數傳遞給**方法。本示例建立乙個 asynccallback 委託並開始接受網路連線。
[visual basic]
listener.beginaccept( _
new asynccallback(socketlistener.acceptcallback),_
listener)
[c#]
listener.beginaccept(
new asynccallback(socketlistener.acceptcallback),
listener);
非同步套接字使用系統執行緒池中的執行緒處理傳入的連線。乙個執行緒負責接受連線,另一線程用於處理每個傳入的連線,還有乙個執行緒負責接收連線資料。這些執行緒可以是同乙個執行緒,具體取決於執行緒池所分配的執行緒。在下面的示例中,system.threading.manualresetevent 類掛起主線程的執行並在執行可以繼續時發出訊號。
下面的示例顯示在本地計算機上建立非同步 tcp/ip 套接字並開始接受連線的非同步方法。它假定以下內容:存在乙個名為 alldone 的全域性 manualresetevent,該方法是乙個名為 socketlistener 的類的成員,以及定義了乙個名為 acceptcallback 的**方法。
[visual basic]
public sub startlistening()
dim iphostinfo as iphostentry = dns.resolve(dns.gethostname())
dim localep = new ipendpoint(iphostinfo.addresslist(0), 11000)
console.writeline("local address and port : ", localep.tostring())
dim listener as new socket(localep.address.addressfamily, _
sockettype.stream, protocoltype.tcp)
trylistener.bind(localep)
s.listen(10)
while true
alldone.reset()
console.writeline("waiting for a connection...")
listener.beginaccept(new _
asynccallback(socketlistener.acceptcallback), _
listener)
alldone.waitone()
end while
catch e as exception
console.writeline(e.tostring())
end try
console.writeline("closing the listener...")
end sub 'startlistening
[c#]
public void startlistening() ",localep.tostring());
socket listener = new socket( localep.address.addressfamily,
sockettype.stream, protocoltype.tcp );
try
} catch (exception e)
console.writeline( "closing the listener...");
}接受**方法(即前例中的 acceptcallback)負責向主應用程式發出訊號,讓它繼續執行處理、建立與客戶端的連線並開始非同步讀取客戶端資料。下面的示例是 acceptcallback 方法實現的第一部分。該方法的此節向主應用程式執行緒發出訊號,讓它繼續處理並建立與客戶端的連線。它採用乙個名為 alldone 的全域性 manualresetevent。
[visual basic]
public sub acceptcallback(ar as iasyncresult)
alldone.set()
dim listener as socket = ctype(ar.asyncstate, socket)
dim handler as socket = listener.endaccept(ar)
' additional code to read data goes here.
end sub 'acceptcallback
[c#]
public void acceptcallback(iasyncresult ar)
從客戶端套接字讀取資料需要乙個在非同步呼叫之間傳遞值的狀態物件。下面的示例實現乙個用於從遠端客戶端接收字串的狀態物件。它包含以下各項的字段:客戶端套接字,用於接收資料的資料緩衝區,以及用於建立客戶端傳送的資料字串的 stringbuilder。將這些字段放在該狀態物件中,使這些欄位的值在多個呼叫之間得以保留,以便從客戶端套接字讀取資料。
[visual basic]
public class stateobject
public worksocket as socket = nothing
public buffersize as integer = 1024
public buffer(buffersize) as byte
public sb as new stringbuilder()
end class 'stateobject
[c#]
public class stateobject
開始從客戶端套接字接收資料的 acceptcallback 方法的此節首先初始化 stateobject 類的乙個例項,然後呼叫 beginreceive 方法以開始從客戶端套接字非同步讀取資料。
下面的示例顯示了完整的 acceptcallback 方法。它假定以下內容:存在乙個名為 alldone 的 manualresetevent,定義了 stateobject 類,以及在名為 socketlistener 的類中定義了 readcallback 方法。
[visual basic]
public shared sub acceptcallback(ar as iasyncresult)
' get the socket that handles the client request.
dim listener as socket = ctype(ar.asyncstate, socket)
dim handler as socket = listener.endaccept(ar)
' signal the main thread to continue.
alldone.set()
' create the state object.
dim state as new stateobject()
state.worksocket = handler
handler.beginreceive(state.buffer, 0, state.buffersize, 0, _
addressof asynchronoussocketlistener.readcallback, state)
end sub 'acceptcallback
[c#]
public static void acceptcallback(iasyncresult ar)
需要為非同步套接字伺服器實現的 final 方法是返回客戶端傳送的資料的讀取**方法。與接受**方法一樣,讀取**方法也是乙個 asynccallback 委託。該方法將來自客戶端套接字的乙個或多個位元組讀入資料緩衝區,然後再次呼叫 beginreceive 方法,直到客戶端傳送的資料完成為止。從客戶端讀取整個訊息後,在控制台上顯示字串,並關閉處理與客戶端的連線的伺服器套接字。
下面的示例實現 readcallback 方法。它假定定義了 stateobject 類。
[visual basic]
[c#]
套接字實現Udp伺服器
udp伺服器的實現與tcp之間是很有差別的,下面我們來說要注意的幾點 首先 需要呼叫socket建立套接字 socket函式的引數與tcp呼叫時有點不一樣,udp是資料報傳輸,所以傳輸的型別是要改為sock dgram,也就是socket函式的第二個引數需要更改 呼叫bind來繫結伺服器,所以我們需...
流式套接字客戶端 伺服器程式設計
1 客戶端向伺服器發出日期請求字串,如 d y a t等 2 伺服器從網路接收到日期時間請求字串後,根據字串格式生成對應的日期時間值返回給客戶端 為了簡化程式美圖出套接字變成的關鍵內容,該例項略去了對請求字串進行合法的校驗的處理。伺服器端程式 include include include incl...
使用套接字實現簡單TCP伺服器客戶端模型
利用套接字實現乙個簡單的tcp伺服器客戶端模型基本步驟如下 1.建立套接字 include include int socket int domain,int type,int protocol 引數描述 domian 協議域,af inet 對應 ipv4,af inet6 對應 ipv6,af ...