using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading;namespace GodzEye.core.TcpSocket { #region globals event declaration #region Socket_Server events public delegate void Socket_Server_Error_EventHandler(Socket_Server sender, EventArgs_Exception e); public delegate void Socket_Server_New_Connection_EventHandler(Socket_Server sender, EventArgs_Socket s); public delegate void Socket_Server_Stopped_EventHandler(Socket_Server sender, EventArgs e);// no event args public delegate void Socket_Server_Started_EventHandler(Socket_Server sender, EventArgs e);// no event args #endregion #region Socket_Data events public delegate void Socket_Data_Error_EventHandler(Socket_Data sender, EventArgs_Exception e); public delegate void Socket_Data_DataArrival_EventHandler(Socket_Data sender, EventArgs_ReceiveDataSocket e); public delegate void Socket_Data_Closed_by_Remote_Side_EventHandler(Socket_Data sender, EventArgs e);// no event args public delegate void Socket_Data_Connected_To_Remote_Host_EventHandler(Socket_Data sender, EventArgs e);// no event args public delegate void Socket_Data_Send_Progress_EventHandler(Socket_Data sender, EventArgs_Send_Progress_Socket_Data e); public delegate void Socket_Data_Send_Completed_EventHandler(Socket_Data sender, EventArgs e);// no event args #endregion #endregion #region eventArgs object /// <summary> /// used by Socket_Data_Send_Progress_EventHandler /// contains bytes_sent,bytes_remaining,bytes_total /// </summary> public class EventArgs_Send_Progress_Socket_Data:EventArgs { /// <summary> /// number of byte that have been sent /// </summary> public readonly int bytes_sent; /// <summary> /// number of byte that remain to be sent /// </summary> public readonly int bytes_remaining; /// <summary> /// number of total bytes (bytes_sent+bytes_remaining) /// </summary> public readonly int bytes_total; public EventArgs_Send_Progress_Socket_Data(int bytes_sent,int bytes_remaining,int bytes_total) { this.bytes_sent=bytes_sent; this.bytes_remaining=bytes_remaining; this.bytes_total=bytes_total; } } /// <summary> /// used by Socket_Data_DataArrival_EventHandler /// contains buffer,buffer_size /// </summary> public class EventArgs_ReceiveDataSocket:EventArgs { /* /// <summary> /// data in string /// </summary> public readonly string data; */ /// <summary> /// data in byte[] /// </summary> public readonly byte[] buffer; /// <summary> /// data length for data or buffer /// </summary> public readonly int buffer_size; //public EventArgs_ReceiveDataSocket(string strdata,byte[] bytebuffer,int intdata_size) public EventArgs_ReceiveDataSocket(byte[] bytebuffer,int intdata_size) { //data=strdata; buffer=bytebuffer; buffer_size=intdata_size; } } /// <summary> /// used to raise Exception /// contains exception /// </summary> public class EventArgs_Exception:EventArgs { public readonly Exception exception; public EventArgs_Exception(Exception e) { exception=e; } } /// <summary> /// used by event_Socket_Server_New_Connection /// contains socket /// </summary> public class EventArgs_Socket:EventArgs { public Socket socket; public EventArgs_Socket(Socket s) { socket=s; } } #endregion #region class Socket_Server public class Socket_Server { #region events
public event Socket_Server_Error_EventHandler event_Socket_Server_Error; public event Socket_Server_New_Connection_EventHandler event_Socket_Server_New_Connection; public event Socket_Server_Stopped_EventHandler event_Socket_Server_Stopped; public event Socket_Server_Started_EventHandler event_Socket_Server_Started; #endregion #region const
private const int default_port=0;//6500; private const int default_max_length_queue_for_pending_connections=10; #endregion #region members private int port; private string ip; private Socket srvsocket; private int max_length_queue_for_pending_connections; #endregion #region members_access public void set_max_length_queue_for_pending_connections(int max,bool restart_server_if_needed) { try {
} public int get_max_length_queue_for_pending_connections() { return max_length_queue_for_pending_connections; } public void set_port(int port,bool restart_server_if_needed) // return the value of listen { try { this.port=port; if (!restart_server_if_needed) return ; listen(); } catch (Exception e) { throw e; } } public int get_port() { return port; } public void set_ip(string ip,bool restart_server_if_needed) { try { this.ip=ip; if (!restart_server_if_needed) return ; listen(); } catch (Exception e) { throw e; } } public string get_ip() { return this.ip; } #endregion #region constructors private void common_constructor() { this.max_length_queue_for_pending_connections=default_max_length_queue_for_pending_connections; }
public Socket_Server() { this.port=default_port; this.common_constructor(); } public Socket_Server(int port) { this.port=port; this.common_constructor(); } public Socket_Server(string ip) { this.ip=ip; this.common_constructor(); } public Socket_Server(string ip,int port) { this.ip=ip; this.port=port; this.common_constructor(); } #endregion #region methodes public void start() { ThreadStart myThreadStart = new ThreadStart(listen); Thread myThread =new Thread(myThreadStart); myThread.Start(); } public void stop() { try { if (this.srvsocket!=null) this.srvsocket.Close(); } catch (Exception e) { if (this.event_Socket_Server_Error!=null) this.event_Socket_Server_Error(this,new EventArgs_Exception(e)); } } /// <summary> /// make all needed to launch server /// send event_Socket_Server_Started if success /// </summary> private void listen() { try { IPHostEntry iphe; IPAddress ipaddr; IPEndPoint localep; //stop server if it was runing this.stop(); // resolve ip if (ip=="" || ip==null) { ipaddr=System.Net.IPAddress.Any; } else { try { // don't resolve if ip is like xxx.yyy.uuu.vvv ipaddr=System.Net.IPAddress.Parse(ip); } catch { // else resolve try { iphe=System.Net.Dns.Resolve(ip); } catch(Exception e) { this.event_Socket_Server_Error(this,new EventArgs_Exception(e)); return; } ipaddr=iphe.AddressList[0]; } } // make local end point localep = new IPEndPoint(ipaddr,port); // create socket this.srvsocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); this.srvsocket.Bind(localep); this.port=((IPEndPoint)this.srvsocket.LocalEndPoint).Port;// in case of null port given this.srvsocket.Listen(max_length_queue_for_pending_connections); // send event_Socket_Server_Started if (this.event_Socket_Server_Started!=null) this.event_Socket_Server_Started(this,new EventArgs()); // accept connections Socket mySocket; while(true) { mySocket=srvsocket.Accept();//blocking // send event_Socket_Server_New_Connection if (event_Socket_Server_New_Connection!=null) #if (!DEBUG) try// avoid to close server on some programmer's error in the eventhandler function #endif { this.event_Socket_Server_New_Connection(this,new EventArgs_Socket(mySocket)); } #if (!DEBUG) catch{} #endif } } catch (Exception e) { if (e is SocketException) { SocketException se; se=(SocketException) e; if (se.ErrorCode==10004)// accept canceled because of socket closing { if (this.event_Socket_Server_Stopped!=null) this.event_Socket_Server_Stopped(this,new EventArgs()); return; } } // send event_Socket_Server_Error if (this.event_Socket_Server_Error!=null) this.event_Socket_Server_Error(this,new EventArgs_Exception(e)); // close socket this.stop(); // send event_Socket_Server_Stopped if (this.event_Socket_Server_Stopped!=null) this.event_Socket_Server_Stopped(this,new EventArgs()); } } #endregion } #endregion #region class Socket_Data public class Socket_Data { #region events public event Socket_Data_Error_EventHandler event_Socket_Data_Error; public event Socket_Data_DataArrival_EventHandler event_Socket_Data_DataArrival; public event Socket_Data_Closed_by_Remote_Side_EventHandler event_Socket_Data_Closed_by_Remote_Side; public event Socket_Data_Connected_To_Remote_Host_EventHandler event_Socket_Data_Connected_To_Remote_Host; public event Socket_Data_Send_Progress_EventHandler event_Socket_Data_Send_Progress; public event Socket_Data_Send_Completed_EventHandler event_Socket_Data_Send_Completed; #endregion #region const private const int default_buffer_size=4096; #endregion #region members private IPEndPoint remote_IPendpoint; private Socket datasocket; private int buffer_size; private string my_connect_remote_ip; private int my_connect_remote_port; private System.Collections.Queue send_queue; private bool locally_closed=false; private bool b_cancel_send=false; private int my_local_port; private System.Threading.ManualResetEvent evt_more_data_to_send=new System.Threading.ManualResetEvent(false); private System.Threading.ManualResetEvent evt_close=new System.Threading.ManualResetEvent(false); private System.Threading.AutoResetEvent evt_unlocked_send_queue=new System.Threading.AutoResetEvent(true); #endregion public bool Connected { get { return this.datasocket.Connected; } } #region members_access public IPEndPoint LocalIPEndPoint { get { return (IPEndPoint)datasocket.LocalEndPoint; } } public IPEndPoint RemoteIPEndPoint { get { return this.remote_IPendpoint; } } public string RemoteIP { get { return this.my_connect_remote_ip; } } public ushort RemotePort { get { return (ushort)this.my_connect_remote_port; } } #endregion #region constructors #region constructors used for connecting to remote ip /// <summary> /// used for client socket. Just add event and use the connect methode after this constructor /// </summary> public Socket_Data() { this.buffer_size=default_buffer_size; this.my_local_port=0; // create a socket this.datasocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); this.commun_constructor(); } /// <summary> /// used for client socket. Just add event and use the connect methode after this constructor /// </summary> /// <param name="buffer_size">size of buffer used for sending data</param> public Socket_Data(int buffer_size) { this.buffer_size=buffer_size; this.my_local_port=0; // create a socket this.datasocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); this.commun_constructor(); } /// <summary> /// used for client socket. Just add event and use the connect methode after this constructor /// </summary> /// <param name="buffer_size">size of buffer used for sending data</param> public Socket_Data(int buffer_size,int local_port) { this.buffer_size=buffer_size; this.my_local_port=local_port; // create a socket this.datasocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); this.commun_constructor(); }
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;namespace GodzEye.core.TcpSocket
{
#region globals event declaration #region Socket_Server events public delegate void Socket_Server_Error_EventHandler(Socket_Server sender, EventArgs_Exception e);
public delegate void Socket_Server_New_Connection_EventHandler(Socket_Server sender, EventArgs_Socket s);
public delegate void Socket_Server_Stopped_EventHandler(Socket_Server sender, EventArgs e);// no event args
public delegate void Socket_Server_Started_EventHandler(Socket_Server sender, EventArgs e);// no event args #endregion #region Socket_Data events
public delegate void Socket_Data_Error_EventHandler(Socket_Data sender, EventArgs_Exception e);
public delegate void Socket_Data_DataArrival_EventHandler(Socket_Data sender, EventArgs_ReceiveDataSocket e);
public delegate void Socket_Data_Closed_by_Remote_Side_EventHandler(Socket_Data sender, EventArgs e);// no event args
public delegate void Socket_Data_Connected_To_Remote_Host_EventHandler(Socket_Data sender, EventArgs e);// no event args
public delegate void Socket_Data_Send_Progress_EventHandler(Socket_Data sender, EventArgs_Send_Progress_Socket_Data e);
public delegate void Socket_Data_Send_Completed_EventHandler(Socket_Data sender, EventArgs e);// no event args
#endregion #endregion #region eventArgs object
/// <summary>
/// used by Socket_Data_Send_Progress_EventHandler
/// contains bytes_sent,bytes_remaining,bytes_total
/// </summary>
public class EventArgs_Send_Progress_Socket_Data:EventArgs
{
/// <summary>
/// number of byte that have been sent
/// </summary>
public readonly int bytes_sent;
/// <summary>
/// number of byte that remain to be sent
/// </summary>
public readonly int bytes_remaining;
/// <summary>
/// number of total bytes (bytes_sent+bytes_remaining)
/// </summary>
public readonly int bytes_total;
public EventArgs_Send_Progress_Socket_Data(int bytes_sent,int bytes_remaining,int bytes_total)
{
this.bytes_sent=bytes_sent;
this.bytes_remaining=bytes_remaining;
this.bytes_total=bytes_total;
}
}
/// <summary>
/// used by Socket_Data_DataArrival_EventHandler
/// contains buffer,buffer_size
/// </summary>
public class EventArgs_ReceiveDataSocket:EventArgs
{
/*
/// <summary>
/// data in string
/// </summary>
public readonly string data;
*/
/// <summary>
/// data in byte[]
/// </summary>
public readonly byte[] buffer;
/// <summary>
/// data length for data or buffer
/// </summary>
public readonly int buffer_size;
//public EventArgs_ReceiveDataSocket(string strdata,byte[] bytebuffer,int intdata_size)
public EventArgs_ReceiveDataSocket(byte[] bytebuffer,int intdata_size)
{
//data=strdata;
buffer=bytebuffer;
buffer_size=intdata_size;
}
}
/// <summary>
/// used to raise Exception
/// contains exception
/// </summary>
public class EventArgs_Exception:EventArgs
{
public readonly Exception exception;
public EventArgs_Exception(Exception e)
{
exception=e;
}
}
/// <summary>
/// used by event_Socket_Server_New_Connection
/// contains socket
/// </summary>
public class EventArgs_Socket:EventArgs
{
public Socket socket;
public EventArgs_Socket(Socket s)
{
socket=s;
}
}
#endregion #region class Socket_Server
public class Socket_Server
{ #region events
public event Socket_Server_Error_EventHandler event_Socket_Server_Error;
public event Socket_Server_New_Connection_EventHandler event_Socket_Server_New_Connection;
public event Socket_Server_Stopped_EventHandler event_Socket_Server_Stopped;
public event Socket_Server_Started_EventHandler event_Socket_Server_Started; #endregion #region const
private const int default_port=0;//6500;
private const int default_max_length_queue_for_pending_connections=10; #endregion #region members private int port;
private string ip;
private Socket srvsocket;
private int max_length_queue_for_pending_connections; #endregion #region members_access public void set_max_length_queue_for_pending_connections(int max,bool restart_server_if_needed)
{
try
{
if (!restart_server_if_needed) return ;
listen();
}
catch (Exception e)
{
throw e;
}
} public int get_max_length_queue_for_pending_connections()
{
return max_length_queue_for_pending_connections;
} public void set_port(int port,bool restart_server_if_needed)
// return the value of listen
{
try
{
this.port=port;
if (!restart_server_if_needed) return ;
listen();
}
catch (Exception e)
{
throw e;
}
}
public int get_port()
{
return port;
}
public void set_ip(string ip,bool restart_server_if_needed)
{
try
{
this.ip=ip;
if (!restart_server_if_needed) return ;
listen();
}
catch (Exception e)
{
throw e;
}
} public string get_ip()
{
return this.ip;
}
#endregion #region constructors private void common_constructor()
{
this.max_length_queue_for_pending_connections=default_max_length_queue_for_pending_connections;
}
public Socket_Server()
{
this.port=default_port;
this.common_constructor();
}
public Socket_Server(int port)
{
this.port=port;
this.common_constructor();
}
public Socket_Server(string ip)
{
this.ip=ip;
this.common_constructor();
} public Socket_Server(string ip,int port)
{
this.ip=ip;
this.port=port;
this.common_constructor();
}
#endregion #region methodes public void start()
{
ThreadStart myThreadStart = new ThreadStart(listen);
Thread myThread =new Thread(myThreadStart);
myThread.Start();
} public void stop()
{
try
{
if (this.srvsocket!=null)
this.srvsocket.Close();
}
catch (Exception e)
{
if (this.event_Socket_Server_Error!=null)
this.event_Socket_Server_Error(this,new EventArgs_Exception(e));
}
} /// <summary>
/// make all needed to launch server
/// send event_Socket_Server_Started if success
/// </summary>
private void listen()
{
try
{
IPHostEntry iphe;
IPAddress ipaddr;
IPEndPoint localep; //stop server if it was runing
this.stop(); // resolve ip
if (ip=="" || ip==null)
{
ipaddr=System.Net.IPAddress.Any;
}
else
{
try
{
// don't resolve if ip is like xxx.yyy.uuu.vvv
ipaddr=System.Net.IPAddress.Parse(ip);
}
catch
{
// else resolve
try
{
iphe=System.Net.Dns.Resolve(ip);
}
catch(Exception e)
{
this.event_Socket_Server_Error(this,new EventArgs_Exception(e));
return;
}
ipaddr=iphe.AddressList[0];
}
}
// make local end point
localep = new IPEndPoint(ipaddr,port);
// create socket
this.srvsocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
this.srvsocket.Bind(localep);
this.port=((IPEndPoint)this.srvsocket.LocalEndPoint).Port;// in case of null port given
this.srvsocket.Listen(max_length_queue_for_pending_connections);
// send event_Socket_Server_Started
if (this.event_Socket_Server_Started!=null)
this.event_Socket_Server_Started(this,new EventArgs());
// accept connections
Socket mySocket;
while(true)
{
mySocket=srvsocket.Accept();//blocking
// send event_Socket_Server_New_Connection
if (event_Socket_Server_New_Connection!=null)
#if (!DEBUG)
try// avoid to close server on some programmer's error in the eventhandler function
#endif
{
this.event_Socket_Server_New_Connection(this,new EventArgs_Socket(mySocket));
}
#if (!DEBUG)
catch{}
#endif
} } catch (Exception e)
{
if (e is SocketException)
{
SocketException se;
se=(SocketException) e;
if (se.ErrorCode==10004)// accept canceled because of socket closing
{
if (this.event_Socket_Server_Stopped!=null)
this.event_Socket_Server_Stopped(this,new EventArgs());
return;
}
}
// send event_Socket_Server_Error
if (this.event_Socket_Server_Error!=null)
this.event_Socket_Server_Error(this,new EventArgs_Exception(e));
// close socket
this.stop();
// send event_Socket_Server_Stopped
if (this.event_Socket_Server_Stopped!=null)
this.event_Socket_Server_Stopped(this,new EventArgs());
}
}
#endregion }
#endregion #region class Socket_Data
public class Socket_Data
{ #region events
public event Socket_Data_Error_EventHandler event_Socket_Data_Error;
public event Socket_Data_DataArrival_EventHandler event_Socket_Data_DataArrival;
public event Socket_Data_Closed_by_Remote_Side_EventHandler event_Socket_Data_Closed_by_Remote_Side;
public event Socket_Data_Connected_To_Remote_Host_EventHandler event_Socket_Data_Connected_To_Remote_Host;
public event Socket_Data_Send_Progress_EventHandler event_Socket_Data_Send_Progress;
public event Socket_Data_Send_Completed_EventHandler event_Socket_Data_Send_Completed;
#endregion #region const
private const int default_buffer_size=4096;
#endregion #region members
private IPEndPoint remote_IPendpoint;
private Socket datasocket;
private int buffer_size;
private string my_connect_remote_ip;
private int my_connect_remote_port;
private System.Collections.Queue send_queue;
private bool locally_closed=false;
private bool b_cancel_send=false;
private int my_local_port;
private System.Threading.ManualResetEvent evt_more_data_to_send=new System.Threading.ManualResetEvent(false);
private System.Threading.ManualResetEvent evt_close=new System.Threading.ManualResetEvent(false);
private System.Threading.AutoResetEvent evt_unlocked_send_queue=new System.Threading.AutoResetEvent(true);
#endregion
public bool Connected
{
get
{
return this.datasocket.Connected;
}
}
#region members_access public IPEndPoint LocalIPEndPoint
{
get
{
return (IPEndPoint)datasocket.LocalEndPoint;
}
}
public IPEndPoint RemoteIPEndPoint
{
get
{
return this.remote_IPendpoint;
}
}
public string RemoteIP
{
get
{
return this.my_connect_remote_ip;
}
}
public ushort RemotePort
{
get
{
return (ushort)this.my_connect_remote_port;
}
}
#endregion #region constructors #region constructors used for connecting to remote ip /// <summary>
/// used for client socket. Just add event and use the connect methode after this constructor
/// </summary>
public Socket_Data()
{
this.buffer_size=default_buffer_size;
this.my_local_port=0; // create a socket
this.datasocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); this.commun_constructor();
} /// <summary>
/// used for client socket. Just add event and use the connect methode after this constructor
/// </summary>
/// <param name="buffer_size">size of buffer used for sending data</param>
public Socket_Data(int buffer_size)
{
this.buffer_size=buffer_size;
this.my_local_port=0; // create a socket
this.datasocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); this.commun_constructor();
}
/// <summary>
/// used for client socket. Just add event and use the connect methode after this constructor
/// </summary>
/// <param name="buffer_size">size of buffer used for sending data</param>
public Socket_Data(int buffer_size,int local_port)
{
this.buffer_size=buffer_size;
this.my_local_port=local_port; // create a socket
this.datasocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
this.commun_constructor();
}
谢谢!
[email protected]
谢谢了。
[email protected]
[email protected]
学习ING