اشارك معكم هذا الكلاس في إصدارة ال Beta Version
Asynchronous Sockets هي كلاسات موجودة في الدوت نت لعملية الإتصال بالشبكات اللامتزامنة بحيث يعمل البرنامج على إرسال و إستقبال المعلومات من و الي الشبكة بدون إيقاف البرنامج لإنتظار عملية الإرسال او الأستقبال(Synchronous Sockets).
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace ClientSocket
{
class ClientSocket
{
#region Declarations
Socket sckClient;
String mHost;
int mPort;
public enum SocketState { Closed, Connecting, Connected }
SocketState mState;
#endregion
#region Events
public delegate void ConnectedHandler(Object Sender);
public delegate void DisconnectedHandler(Object Sender);
public delegate void DataReceivedHandler(Object Sender, String Text);
public delegate void DataSendHandler(Object Sender);
public event ConnectedHandler Connected;
public event DisconnectedHandler Closed;
public event DataReceivedHandler DataReceived;
public event DataSendHandler DataSent;
#endregion
#region Helper Functions
public IPAddress ResolveAddress(String host)
{
IPHostEntry iph = Dns.GetHostEntry(host);
return iph.AddressList[0];
}
#endregion
#region Properties
public String Host
{
set
{
mHost = value;
}
get
{
return mHost;
}
}
public int Port
{
set
{
mPort = value;
}
get
{
return mPort;
}
}
public SocketState SockState
{
get
{
return mState;
}
}
#endregion
public ClientSocket()
{
//Create new Socket
sckClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mHost = "";
mPort = 0;
mState = SocketState.Closed;
}
#region Public functions
public void Connect()
{
//Start connection
if (mHost == String.Empty)
{
throw new ArgumentException("Host was not specified!");
}
else
{
try
{
EndPoint ep = new IPEndPoint(ResolveAddress(Host), mPort);
sckClient.BeginConnect(ep, new AsyncCallback(ConnectedCallback), sckClient);
mState = SocketState.Connecting;
}
catch (SocketException)
{
if (sckClient.Connected) mState = SocketState.Connected;
else
{
mState = SocketState.Closed;
Closed(this);
}
}
}
}
public void Close()
{
if (sckClient != null && sckClient.Connected)
{
sckClient.Shutdown(SocketShutdown.Both);
sckClient.Close();
mState = SocketState.Closed;
sckClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Closed(this);
}
}
public void Send(String Data)
{
try
{
Byte[] buffer = Encoding.ASCII.GetBytes(Data);
sckClient.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(DataSendCallback), sckClient);
}
catch (SocketException)
{
if (sckClient.Connected) mState = SocketState.Connected;
else
{
mState = SocketState.Closed;
Closed(this);
}
}
}
public void Send(Byte[] Buffer, int offset, int length)
{
try
{
sckClient.BeginSend(Buffer, offset, length, SocketFlags.None, new AsyncCallback(DataSendCallback), sckClient);
}
catch (SocketException)
{
if (sckClient.Connected) mState = SocketState.Connected;
else
{
mState = SocketState.Closed;
Closed(this);
}
}
}
#endregion
#region Callbacks
public void ConnectedCallback(IAsyncResult ar)
{
try
{
Socket s = (Socket)ar.AsyncState;
s.EndConnect(ar);
mState = SocketState.Connected;
//Begin recevie
StateObject sb = new StateObject();
sb.ClientSocket = sckClient;
s.BeginReceive(sb.Buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, new AsyncCallback(DataReceiveCallback), sb);
//Raise connection event
Connected(this);
}
catch (SocketException)
{
if (sckClient.Connected) mState = SocketState.Connected;
else
{
mState = SocketState.Closed;
Closed(this);
}
}
}
public void DataReceiveCallback(IAsyncResult ar)
{
try
{
StateObject sb = (StateObject)ar.AsyncState;
int BytesToRead = sb.ClientSocket.EndReceive(ar);
String RecText = Encoding.ASCII.GetString(sb.Buffer, 0, BytesToRead);
if (RecText.Trim() != String.Empty)
DataReceived(this, RecText);
//Begin recevie
sb.ClientSocket.BeginReceive(sb.Buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, new AsyncCallback(DataReceiveCallback), sb);
}
catch (SocketException)
{
if (sckClient.Connected) mState = SocketState.Connected;
else
{
mState = SocketState.Closed;
Closed(this);
}
}
}
public void DataSendCallback(IAsyncResult ar)
{
try
{
Socket s = (Socket)ar.AsyncState;
s.EndSend(ar);
DataSent(this);
}
catch (SocketException)
{
if (sckClient.Connected) mState = SocketState.Connected;
else
{
mState = SocketState.Closed;
Closed(this);
}
}
}
#endregion
}
}هذا الكلاس هو كلاس شبيه بأداة الونسوك و التي تقدم خدمات ال Event-Driven Network Programming و التي كانت اكثر من رائعة بصراحة, و اقدم لكم هذا الكلاس المتواضع و الشبيه بالأداة نوعا ما و الموجودة في الفجوال بيسك 6.0.
كيفية الإستخدام:
لتعريف المتغير من نوع هذا الكلاس تقوم بوضع الكود التالي:
ClientSocket cs;
و من ثم يجب علينا ان نقوم بعمل Initialize لهذا الObject كالتالي:
cs = new ClientSocket(); cs.Connected += new ClientSocket.ConnectedHandler(Connected); cs.Closed += new ClientSocket.DisconnectedHandler(onClose); cs.DataSent += new ClientSocket.DataSendHandler(DataSent); cs.DataReceived += new ClientSocket.DataReceivedHandler(DataReceived);
طبعا الكود الذي يلي سطر ال New هو كود لعملية ربط الأحداث بدالات قمنا بتعريفها لإستقبال المعلومات عن الConnection.
الأول يقوم بربط دالةConnected في الفورم الخاص بنا بالحدث Connected في السوكيت. و الثاني لإستقبال حدث ال Close لل Connection. اما الثالث و الرابع لعمليات أرسال البيانات و إستقبالها.
هذه هي تعريفات الدالات التي تستعدى عند قيام الحدث
void onClose(object sender)
{
MessageBox.Show("Connection closed");
}
void DataSent(object sender)
{
MessageBox.Show("Data sent");
}
void DataReceived(object sender, String RecText)
{
txtMsgs.Text += "Received\n";
txtMsgs.Text += RecText;
}
void Connected(object sender)
{
MessageBox.Show("Connected");
}و كود الزر للقيام بعملية البدء ال Connection
private void btnConnect_Click(object sender, EventArgs e)
{
cs.Host = txtHost.Text;
cs.Port = Int32.Parse(txtPort.Text);
cs.Connect();
}حيث قمنا بأخذ قيم ال Host و Port من مربعات نصوص. و اعطيناها للكلاس ليقوم بعملية بدء الإتصال.
اما بالنسبة لإرسال رسالة
private void btnSend_Click(object sender, EventArgs e)
{
cs.Send(txtMsg.Text + "\n");
}طبعا الرجاء الإبلاغ عن الأخطاء عند إستخدام الكلاس و انا مستعد لأي سؤال.
طبعا يمكن إستخدام هذا الكلاس لتسهيل عملية عمل برامج المحادثة Client-Server وغيرها من برامج الشبكات
سوف اقوم بوضع كلاس ال ServerSocket قريبا أن شاء الله.
مع تمنياتي لكم بالتوفيق
راكان الحنيطي


تسجيل الدخول
التسجيل
المساعدة


ارجع للأعلى
متعدد الإقتباسات


