以下非同步(異步)示例全部使用tcp協議.
1.在編寫服務端及客戶端代碼之前,先編寫一個共用的用於保存接收信息的類:
//
接收到的數據 State object for receiving data from remote device.
public
class
StateObject
{
//
Client socket.
public
Socket workSocket
=
null
;
//
Size of receive buffer.
public
const
int
BufferSize
=
256
;
//
Receive buffer.
public
byte
[] buffer
=
new
byte
[BufferSize];
//
Received data string.
public
StringBuilder sb
=
new
StringBuilder();
}
2.服務端示例:
示例程序创建一个接收来自客户端的连接请求的服务器。该服务器是用异步套接字生成的,因此在等待来自客户端的连接时不挂起服务器应用程序的执行。该应用程序接收来自客户端的字符串,在控制台显示该字符串,然后将该字符串回显到客户端。来自客户端的字符串必须包含字符串“<EOF>”, 以发出表示消息结尾的信号。
public
class
AsynchronousSocketListener
{
//
定義線程標識
public
static
ManualResetEvent allDone
=
new
ManualResetEvent(
false
);
public
AsynchronousSocketListener()
{
}
public
static
void
StartListening()
{
//
暫存接收數據
byte
[] bytes
=
new
Byte[
1024
];
//
建立本地端口
//
The DNS name of the computer running the listener is "host.contoso.com".
IPHostEntry ipHostInfo
=
Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress
=
ipHostInfo.AddressList[
0
];
IPEndPoint localEndPoint
=
new
IPEndPoint(ipAddress,
11000
);
//
建立socket
Socket listener
=
new
Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//
Bind本地端口並偵聽連接
try
{
listener.Bind(localEndPoint);
listener.Listen(
100
);
while
(
true
)
{
//
Set the event to nonsignaled state.
allDone.Reset();
//
開始偵聽
Console.WriteLine(
"
Waiting for a connection...
"
);
listener.BeginAccept(
new
AsyncCallback(AcceptCallback), listener);
//
暫停直到有新的連接 Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch
(Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine(
"
Press ENTER to continue...
"
);
Console.Read();
}
public
static
void
AcceptCallback(IAsyncResult ar)
{
//
標識主線程繼續
allDone.Set();
//
Get the socket that handles the client request.
Socket listener
=
(Socket)ar.AsyncState;
Socket handler
=
listener.EndAccept(ar);
//
Create the state object.
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;
//
Retrieve the state object and the handler socket
//
from the asynchronous state object.
StateObject state
=
(StateObject)ar.AsyncState;
Socket handler
=
state.workSocket;
//
Read data from the client socket.
int
bytesRead
=
handler.EndReceive(ar);
if
(bytesRead
>
0
)
{
//
There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer,
0
, bytesRead));
//
檢查是否含有文件尾標識,如果沒有,繼續讀取數據
content
=
state.sb.ToString();
if
(content.IndexOf(
"
<EOF>
"
)
>
-
1
)
{
//
顯示接收到的數據
Console.WriteLine(
"
Read {0} bytes from socket. Data : {1}
"
, content.Length, content);
//
發送數據 Echo the data back to the client.
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
{
//
Retrieve the socket from the state object.
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
;
}
}
3.客戶端示例:
示例程序创建一个连接到服务器的客户端。该客户端是用异步套接字生成的,因此在等待服务器返回响应时不挂起客户端应用程序的执行。该应用程序将字符串发送到服务器,然后在控制台显示该服务器返回的字符串。
public
class
AsynchronousClient
{
//
定義遠程端口
private
const
int
port
=
11000
;
//
ManualResetEvent instances signal completion.
private
static
ManualResetEvent connectDone
=
new
ManualResetEvent(
false
);
private
static
ManualResetEvent sendDone
=
new
ManualResetEvent(
false
);
private
static
ManualResetEvent receiveDone
=
new
ManualResetEvent(
false
);
//
接收到的數據 The response from the remote device.
private
static
String response
=
String.Empty;
private
static
void
StartClient()
{
//
連接遠程設備
try
{
//
建立遠程端口
IPHostEntry ipHostInfo
=
Dns.GetHostEntry(
"
host.contoso.com
"
);
IPAddress ipAddress
=
ipHostInfo.AddressList[
0
];
IPEndPoint remoteEP
=
new
IPEndPoint(ipAddress, port);
//
建立socket
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<EOF>
"
);
sendDone.WaitOne();
//
接收數據
Receive(client);
receiveDone.WaitOne();
//
顯示接收到的數據
Console.WriteLine(
"
Response received : {0}
"
, response);
//
關閉socket
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch
(Exception e)
{
Console.WriteLine(e.ToString());
}
}
private
static
void
ConnectCallback(IAsyncResult ar)
{
try
{
//
Retrieve the socket from the state object.
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
{
//
Create the state object.
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
{
//
Retrieve the state object and the client socket
//
from the asynchronous state object.
StateObject state
=
(StateObject)ar.AsyncState;
Socket client
=
state.workSocket;
//
Read data from the remote device.
int
bytesRead
=
client.EndReceive(ar);
if
(bytesRead
>
0
)
{
//
There might be more data, so store the data received so far.
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)
{
//
將字符串轉化為ascii字節數組
byte
[] byteData
=
Encoding.ASCII.GetBytes(data);
//
開始發送數據
client.BeginSend(byteData,
0
, byteData.Length,
0
,
new
AsyncCallback(SendCallback), client);
}
private
static
void
SendCallback(IAsyncResult ar)
{
try
{
//
Retrieve the socket from the state object.
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
;
}
}
參考文獻: 1. http://www.jb51.net/html/200703/85/8049.htm