詳解C# Socket異步通信實(shí)例
TCPServer
1、使用的通訊通道:socket
2、用到的基本功能:
①Bind,
②Listen,
③BeginAccept
④EndAccept
⑤BeginReceive
⑥EndReceive
3、函數(shù)參數(shù)說明
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
新建socket所使用的參數(shù)均為系統(tǒng)預(yù)定義的量,直接選取使用。
listener.Bind(localEndPoint);
localEndPoint 表示一個(gè)定義完整的終端,包括IP和端口信息。
//new IPEndPoint(IPAddress,port)
//IPAdress.Parse("192.168.1.3")
listener.Listen(100);
監(jiān)聽
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
AsyncCallback(AcceptCallback),一旦連接上后的回調(diào)函數(shù)為AcceptCallback。當(dāng)系統(tǒng)調(diào)用這個(gè)函數(shù)時(shí),自動(dòng)賦予的輸入?yún)?shù)為IAsyncResoult類型變量ar。
listener,連接行為的容器。
Socket handler = listener.EndAccept(ar);
完成連接,返回此時(shí)的socket通道。
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
接收的字節(jié),0,字節(jié)長度,0,接收時(shí)調(diào)用的回調(diào)函數(shù),接收行為的容器。
========
容器的結(jié)構(gòu)類型為:
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
容器至少為一個(gè)socket類型。
===============
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
完成一次連接。數(shù)據(jù)存儲(chǔ)在state.buffer里,bytesRead為讀取的長度。
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
發(fā)送數(shù)據(jù)byteData,回調(diào)函數(shù)SendCallback。容器handler
int bytesSent = handler.EndSend(ar);
發(fā)送完畢,bytesSent發(fā)送字節(jié)數(shù)。
4 程序結(jié)構(gòu)
主程序:
byte[] bytes = new Byte[1024];
IPAddress ipAddress = IPAddress.Parse("192.168.1.104");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// 生成一個(gè)TCP的socket
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
//開啟異步監(jiān)聽socket
Console.WriteLine("Waiting for a connection");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// 讓程序等待,直到連接任務(wù)完成。在AcceptCallback里的適當(dāng)位置放置allDone.Set()語句.
allDone.WaitOne();
}
Console.WriteLine("\nPress ENTER to continue");
Console.Read();
連接行為回調(diào)函數(shù)AcceptCallback:
public static void AcceptCallback(IAsyncResult ar)
{
//添加此命令,讓主線程繼續(xù).
allDone.Set();
// 獲取客戶請(qǐng)求的socket
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// 造一個(gè)容器,并用于接收命令.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
讀取行為的回調(diào)函數(shù)ReadCallback:
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// 從異步state對(duì)象中獲取state和socket對(duì)象.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// 從客戶socket讀取數(shù)據(jù).
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
// 如果接收到數(shù)據(jù),則存起來
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// 檢查是否有結(jié)束標(biāo)記,如果沒有則繼續(xù)讀取
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
//所有數(shù)據(jù)讀取完畢.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content);
// 給客戶端響應(yīng).
Send(handler, content);
}
else
{
// 接收未完成,繼續(xù)接收.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}
發(fā)送消息給客戶端:
private static void Send(Socket handler, String data)
{
// 消息格式轉(zhuǎn)換.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// 開始發(fā)送數(shù)據(jù)給遠(yuǎn)程目標(biāo).
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
// 從state對(duì)象獲取socket.
Socket handler = (Socket)ar.AsyncState;
//完成數(shù)據(jù)發(fā)送
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
在各種行為的回調(diào)函數(shù)中,所對(duì)應(yīng)的socket都從輸入?yún)?shù)的AsyncState屬性獲得。使用(Socket)或者(StateObject)進(jìn)行強(qiáng)制轉(zhuǎn)換。BeginReceive函數(shù)使用的容器為state,因?yàn)樗枰娣艂魉偷臄?shù)據(jù)。
而其余接收或發(fā)送函數(shù)的容器為socket也可。
完整代碼
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
// State object for reading client data asynchronously
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = ;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousSocketListener
{
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public AsynchronousSocketListener()
{
}
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[];
// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
//IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = IPAddress.Parse("...");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, );
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen();
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
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("\nPress ENTER to continue");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
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, , StateObject.BufferSize, , 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 > )
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer, , bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -)
{
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {} bytes from socket. \n Data : {}",content.Length, content);
// Echo the data back to the client.
Send(handler, content);
}
else
{
// Not all data received. Get more.
handler.BeginReceive(state.buffer, , StateObject.BufferSize, , new AsyncCallback(ReadCallback), state);
}
}
}
private static void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, , byteData.Length, ,
new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {} 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 ;
}
}
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
欄 目:C#教程
下一篇:C#對(duì)多個(gè)集合和數(shù)組的操作方法(合并,去重,判斷)
本文標(biāo)題:詳解C# Socket異步通信實(shí)例
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/6100.html
您可能感興趣的文章
- 01-10C#異步綁定數(shù)據(jù)實(shí)現(xiàn)方法
- 01-10C#中Socket通信用法實(shí)例詳解
- 01-10同步調(diào)用和異步調(diào)用WebService
- 01-10C#裝箱和拆箱原理詳解
- 01-10C#類的多態(tài)性詳解
- 01-10C#創(chuàng)建不規(guī)則窗體的4種方式詳解
- 01-10C#中深度復(fù)制和淺度復(fù)制詳解
- 01-10C#數(shù)據(jù)結(jié)構(gòu)之隊(duì)列(Quene)實(shí)例詳解
- 01-10C#數(shù)據(jù)結(jié)構(gòu)之順序表(SeqList)實(shí)例詳解
- 01-10C#編程實(shí)現(xiàn)連接ACCESS數(shù)據(jù)庫實(shí)例詳解


閱讀排行
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置


