Socket服务端代码,写的一般,有兴趣可以一起讨论下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections;
using System.Net.Sockets;
using System.Net;

namespace Forms
{
public class SocketServer
{
/// <summary>
/// 手动下发定时监测对象
/// </summary>
public SendModle publicsendmodle = null;

#region 字段
/// <summary>
/// TCP网络客户端侦听连接对象
/// </summary>
private TcpListener _tcplistener = null;
/// <summary>
/// UDP网络客户端侦听连接对象
/// </summary>
private UdpClient _udplistener = null;
/// <summary>
/// 客户端会话的哈希表(存放SOCKET)
/// </summary>
private Hashtable _hashtable = new Hashtable();
/// <summary>
/// 接受数据线程hashtable
/// </summary>
private Hashtable _threadtable = new Hashtable();
/// <summary>
/// 发送命令thread
/// </summary>
private Hashtable _sendthread = new Hashtable();
/// <summary>
/// 定时从发集合
/// </summary>
private List<Guid> guidlist = new List<Guid>();
/// <summary>
/// TCP主线程
/// </summary>
private Thread startsocketthread;
/// <summary>
/// UDP主线程
/// </summary>
Thread startsocketthread_udp;
/// <summary>
/// TCP手动下发命令线程
/// </summary>
private Thread threadbyhand;
#endregion
#region 属性
/// <summary>
/// ip地址
/// </summary>
private string _ipAddress;
/// <summary>
/// 端口
/// </summary>
private int _port;
/// <summary>
/// 数据包
/// </summary>
private int _maxpacket = 1 * 1024;
/// <summary>
/// 编码方式
/// </summary>
private int _serverencoding;
/// <summary>
/// Socket连接超时
/// </summary>
private int _timeout;
/// <summary>
/// 当前连接数
/// </summary>
public int Currentconncount { get { return _hashtable.Count; } }
/// <summary>
/// 端口
/// </summary>
public int Port { get { return _port; } }
/// <summary>
/// ip地址
/// </summary>
public string IpAddress { get { return _ipAddress; } }
/// <summary>
/// 数据包(默认大小1kb)
/// </summary>
public int Maxpacket { get { return _maxpacket; } }
/// <summary>
/// 编码方式
/// </summary>
public int Serverencoding { get { return _serverencoding; } set { _serverencoding = value; } }
/// <summary>
/// Socket连接超时(秒为单位)
/// </summary>
public int Timeout { get { return _timeout; } set { _timeout = value; } }
#endregion
#region 委托
/// <summary>
/// 与Socket服务器断开连接
/// </summary>
/// <param name="socketGuid">GUID标识</param>
/// <param name="recievemodel">返回数据MODEL</param>
public delegate void SocketClose(Guid socketGuid, ReturnModle recievemodel);
/// <summary>
/// 接受数据
/// </summary>
/// <param name="socketGuid"></param>
/// <param name="recievemodel"></param>
public delegate void DataReceived(Guid socketGuid, ReturnModle recievemodel);
#endregion
#region 事件
/// <summary>
/// 与Socket服务器断开连接事件
/// </summary>
public event SocketClose OnSocketClose;
/// <summary>
/// 接受客户端数据事件
/// </summary>
public event DataReceived OnDataReceived;
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
/// <param name="port">端口号</param>
/// <param name="serverencoding">编码方式</param>
/// <param name="timeout">超时时间</param>
public SocketServer(int port, int serverencoding, int timeout)
{
_port = port;
_serverencoding = serverencoding;
_timeout = timeout;

try
{
_ipAddress = IPAddress.Parse(Dns.GetHostAddresses(Dns.GetHostName())[1].ToString()).ToString();
}
catch
{
_ipAddress = Dns.GetHostAddresses(Dns.GetHostName())[0].ToString();
}
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="port">端口号</param>
/// <param name="serverencoding">编码方式</param>
/// <param name="maxpacket">数据包大小,默认1KB</param>
/// <param name="timeout">超时时间</param>
public SocketServer(int port, int serverencoding, int maxpacket, int timeout)
{
_timeout = timeout;
_port = port;
_maxpacket = maxpacket * 1024;
_serverencoding = serverencoding;

try
{
_ipAddress = IPAddress.Parse(Dns.GetHostAddresses(Dns.GetHostName())[1].ToString()).ToString();
}
catch
{
_ipAddress = Dns.GetHostAddresses(Dns.GetHostName())[0].ToString();
}
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="ipAddress">IP地址</param>
/// <param name="port">端口号</param>
/// <param name="serverencoding">编码方式</param>
/// <param name="timeout">超时时间</param>
public SocketServer(string ipAddress, int port, int serverencoding, int timeout)
{
_timeout = timeout;
_serverencoding = serverencoding;
_ipAddress = ipAddress;
_port = port;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="ipAddress">IP地址</param>
/// <param name="port">端口号</param>
/// <param name="serverencoding">编码方式</param>
/// <param name="maxpacket">数据包大小,默认1KB</param>
/// <param name="timeout">超时时间</param>
public SocketServer(string ipAddress, int port, int serverencoding, int maxpacket, int timeout)
{
_timeout = timeout;
_serverencoding = serverencoding;
_ipAddress = ipAddress;
_port = port;
//赋予数据包最大值
_maxpacket = maxpacket * 1024;
}
#endregion
#region 方法
/// <summary>
/// 启动socket服务
/// </summary>
public void SocketStart(ProtocolType sockettype)
{
if (sockettype == ProtocolType.Tcp)
{
//创建监听器
_tcplistener = new TcpListener(IPAddress.Parse(_ipAddress), _port);
//启动监听器
_tcplistener.Start();

startsocketthread = new Thread(new ThreadStart(StartUp));
startsocketthread.IsBackground = true;
startsocketthread.Start();

threadbyhand = new Thread(() =>
{
while (true)
{
Thread.Sleep(500);

if (publicsendmodle != null)
{
Socket socketclient = (Socket)_hashtable[publicsendmodle.SendGuid];
if (socketclient != null && socketclient.Connected == true)
socketclient.Send(publicsendmodle.Sendbytes);
publicsendmodle = null;
}
}
});
threadbyhand.IsBackground = true;
threadbyhand.Start();
}
else
{
_udplistener = new UdpClient(_port);

startsocketthread_udp = new Thread(new ThreadStart(UDPStartUp));
startsocketthread_udp.IsBackground = true;
startsocketthread_udp.Start();

System.Timers.Timer _SendCmdTimer = new System.Timers.Timer();
_SendCmdTimer.Interval = 60 * 1000;
_SendCmdTimer.Elapsed += new System.Timers.ElapsedEventHandler(TimerElapsedEvent);
_SendCmdTimer.Start();
}
}
/// <summary>
/// 启动socket监听器事件处理方法
/// </summary>
private void StartUp()
{
while (true)
{
try
{
byte[] packetbuff = new byte[_maxpacket];
byte[] sendbuff = new byte[_maxpacket];
Socket newclient = _tcplistener.AcceptSocket();

//获取GUID
Guid socketGuid = Guid.NewGuid();

//将GUID和对应的SOCKET放入HASHTABLE中
_hashtable.Add(socketGuid, newclient);

newclient.ReceiveTimeout = 1000 * _timeout;

//创建SOCKET通信线程
Thread clientthread = new Thread(new ParameterizedThreadStart(ThreadFunc));
clientthread.IsBackground = true;
//已当前SOCKET GUID作为KEY,以当前线程作为VALUE存入盛放接受数据线程HASH表中
_threadtable.Add(socketGuid, clientthread);
//开启SOCKET通讯线程,接受数据
clientthread.Start(socketGuid);
}
catch(Exception e)
{
_tcplistener.Stop();
break;
}

}
}
/// <summary>
/// 线程执行方法
/// </summary>
/// <param name="obj">同一的GUID对象</param>
private void ThreadFunc(object obj)
{
//获取对应通讯的SOCKET对象
Socket clientsocket = (Socket)_hashtable[obj];

int counttest = 0;

while (true)
{
try
{
byte[] packetbuff = new byte[_maxpacket];

int getlength = clientsocket.Receive(packetbuff);

if (counttest > 20)
{
clientsocket.Close();

Guid guid = (Guid)obj;

_hashtable.Remove(guid);

if (OnSocketClose != null)
{
ReturnModle returnmodleobj = new ReturnModle(_hashtable.Count);
OnSocketClose(guid, returnmodleobj);
}

_threadtable.Remove(guid);

break;
}

if (getlength == 0)
counttest++;
else
{
counttest = 0;

string bytestostr = Encoding.GetEncoding(_serverencoding).GetString(packetbuff, 0, getlength);

byte[] packetbuff1 = Encoding.GetEncoding(_serverencoding).GetBytes(bytestostr);

if (OnDataReceived != null)
{
//返回数据MODLE对象,false为当前返回数据是否为有效数据
ReturnModle returnmodleobj = new ReturnModle(packetbuff1, bytestostr, _hashtable.Count, false);
//激活事件处理方法
OnDataReceived((Guid)obj, returnmodleobj);
//根据发送HASHTABLE回去发送命令对象
SendModle sendmodle = (SendModle)_sendthread[obj];
//判断当前发送MODEL是否存在
if (sendmodle != null)
{
//如果当前数据为有效数据
if (returnmodleobj.Isuserfuldata)
{
//获取当前挂起的线程 ;
if (sendmodle.Sendthread != null && sendmodle.Controlevet != null)
{
sendmodle.Isuseful = true;
//如果当前Thread不为NULL且为挂起状态,使它继续运行
sendmodle.Controlevet.Set();
}
}
}
}
}
}
catch (Exception e)
{

clientsocket.Close();

Guid guid = (Guid)obj;

_hashtable.Remove(guid);

if (OnSocketClose != null)
{
ReturnModle returnmodleobj = new ReturnModle(_hashtable.Count);
OnSocketClose(guid, returnmodleobj);
}

_threadtable.Remove(guid);

break;
}
}
}
/// <summary>
/// 启动UDP监听器事件处理方法
/// </summary>
private void UDPStartUp()
{
while (true)
{
bool ipendpointisin = false;

IPEndPoint serveripendpoint = null;

Guid socketguid = Guid.NewGuid();

try
{
byte[] packetbuff = _udplistener.Receive(ref serveripendpoint);

foreach (DictionaryEntry item in _hashtable)
{
IPEndPoint ipendpoint = ((UDPModle)item.Value).Ipendpoint;

if (serveripendpoint.Address.ToString() == ipendpoint.Address.ToString() &&
serveripendpoint.Port == ipendpoint.Port)
{
ipendpointisin = true;
socketguid = (Guid)item.Key;
break;
}
}

string bytestostr = Encoding.GetEncoding(_serverencoding).GetString(packetbuff, 0, packetbuff.Length);

byte[] packetbuff1 = Encoding.GetEncoding(_serverencoding).GetBytes(bytestostr);

if (!ipendpointisin)
{
UDPModle udpmodle = new UDPModle(serveripendpoint, DateTime.Now);
_hashtable.Add(socketguid, udpmodle);
}

if (OnDataReceived != null)
{
UDPModle udpmodle = new UDPModle(serveripendpoint, DateTime.Now);
_hashtable[socketguid] = udpmodle;
ReturnModle returnmodleobj = new ReturnModle(packetbuff1, bytestostr, _hashtable.Count, false);
//激活事件处理方法
OnDataReceived(socketguid, returnmodleobj);
}
}
catch (Exception e)
{
_hashtable.Remove(socketguid);
}
}
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="sendmodle">发送数据对象</param>
public void SendComd(SendModle sendmodle)
{
if (_sendthread[sendmodle.SendGuid] != null)
{
SendModle oldsendmodle = (SendModle)_sendthread[sendmodle.SendGuid];
///如果之前的发送命令线程还没有结束,
///就将发送的index设置为跳出的条件,
///结束挂起,while循环,知道之前的发送线程结束,发送对象释放
oldsendmodle.Currentindex = oldsendmodle.Sendcmd.Count;
oldsendmodle.Controlevet.Set();

while (_sendthread[sendmodle.SendGuid] != null)
{
Thread.Sleep(50);
}
}

//创建线程用于数据的发送
Thread sendthread = new Thread(new ParameterizedThreadStart(SendThread));
sendthread.IsBackground = true;

//根据传入的发送对象创建新的发送对象
SendModle _sendmodle = new SendModle(sendmodle.SendGuid, new AutoResetEvent(false), sendmodle.Sendcmd, sendthread, 0, false);


//添加到数据发送对象HASHTABLE,以发送数据的GUID作为KEY,sendmodle为value
_sendthread.Add(sendmodle.SendGuid, _sendmodle);

sendthread.Start(_sendmodle);
}
/// <summary>
/// 发送命令线程
/// </summary>
private void SendThread(object sendparams)
{
SendModle sendmodle = sendparams as SendModle;

Guid socketGuid = sendmodle.SendGuid;
List<byte[]> sendbytelist = sendmodle.Sendcmd;
//根据发送MODEL获取发送的GUID,根据GUID获取相应的Socket
Socket sendsocket = (Socket)_hashtable[socketGuid];

while (sendmodle.Currentindex < sendbytelist.Count)
{
if (sendsocket != null && sendsocket.Connected)
{
try
{
sendsocket.Send(sendbytelist[sendmodle.Currentindex]);

sendmodle.Controlevet.WaitOne(1000 * 4);

if (sendmodle.Isuseful)
{
sendmodle.Currentindex++;
sendmodle.Isuseful = false;
}
}
catch (Exception ex)
{
break;
}

}
else
break;
}

_sendthread.Remove(socketGuid);
}
/// <summary>
/// 定时检测UDP数据超时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TimerElapsedEvent(object sender, System.Timers.ElapsedEventArgs e)
{
List<Guid> guidlist = new List<Guid>();

foreach (DictionaryEntry item in _hashtable)
{
UDPModle udpmodle = (UDPModle)item.Value;

if ((DateTime.Now - udpmodle.Lastrecievedate) > TimeSpan.FromSeconds(_timeout))

guidlist.Add((Guid)item.Key);
}

foreach (Guid item in guidlist)
{
_hashtable.Remove(item);

if (OnSocketClose != null)
{
ReturnModle returnmodleobj = new ReturnModle(_hashtable.Count);

OnSocketClose(item, returnmodleobj);
}
}
}
#region IDisposable 成员
public void Dispose()
{
if (threadbyhand != null)
{
threadbyhand.Abort();
threadbyhand.Join();
}

#region
//foreach (DictionaryEntry item in _threadtable)
//{
// if (item.Value != null)
// {
// Thread sendthread = (Thread)item.Value;
// sendthread.Abort();
// sendthread.Join();
// }
//}
//foreach (DictionaryEntry item in _sendthread)
//{
// if (item.Value != null)
// {
// Thread sendthread = ((SendModle)item.Value).Sendthread;
// if (((SendModle)item.Value).Controlevet != null)
// ((SendModle)item.Value).Controlevet.Close();
// sendthread.Abort();
// sendthread.Join();
// }
//}
#endregion

if (_udplistener == null)
{
List<Socket> socketlist = new List<Socket>();

foreach (DictionaryEntry item in _hashtable)
if (item.Value != null)
socketlist.Add((Socket)item.Value);

for (int i = socketlist.Count - 1; i >= 0; i--)
{
while (socketlist[i].Connected)
{
socketlist[i].Shutdown(SocketShutdown.Both);
socketlist[i].Close();
}
}
}
#region TCPListener及TCP主线程断开
if (_tcplistener != null)
{
_tcplistener.Stop();
_tcplistener.Server.Close();
}

if (startsocketthread != null)
{
startsocketthread.Abort();
startsocketthread.Join();
}
#endregion

#region UDPListener及UDP主线程断开
if (_udplistener != null)
_udplistener.Close();

if (startsocketthread_udp != null)
{
startsocketthread_udp.Abort();
startsocketthread_udp.Join();
}
#endregion
}
#endregion
#endregion

}

#region 委托参数(实体类)
/// <summary>
/// socket返回数据Modle
/// </summary>
public class ReturnModle
{
/// <summary>
/// 接受到的bytes
/// </summary>
private byte[] _receivebytes;
/// <summary>
/// 连接数量
/// </summary>
private int _connectionCount;
/// <summary>
/// 是否为有效数据
/// </summary>
private bool _isuserfuldata;
/// <summary>
/// 返回字符串
/// </summary>
private string _receivestr;
/// <summary>
/// 是否为有效数据
/// </summary>
public bool Isuserfuldata { get { return _isuserfuldata; } set { _isuserfuldata = value; } }
/// <summary>
/// 连接数量
/// </summary>
public int ConnectionCount { get { return _connectionCount; } set { _connectionCount = value; } }
/// <summary>
/// 接受到的bytes
/// </summary>
public byte[] Receivebytes { get { return _receivebytes; } set { _receivebytes = value; } }
/// <summary>
/// 返回字符串
/// </summary>
public string Receivestr { get { return _receivestr; } set { _receivestr = value; } }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="connectionCount">当前连接数量</param>
public ReturnModle(int connectionCount)
{
_connectionCount = connectionCount;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="receivebytes">返回的bytes</param>
/// <param name="connectionCount">当前连接数量</param>
public ReturnModle(byte[] receivebytes, string receivestr, int connectionCount)
{
_receivestr = receivestr;
_receivebytes = receivebytes;
_connectionCount = connectionCount;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="receivebytes"></param>
/// <param name="connectionCount"></param>
/// <param name="isuserfuldata"></param>
public ReturnModle(byte[] receivebytes, string receivestr, int connectionCount, bool isuserfuldata)
{
_receivestr = receivestr;
_receivebytes = receivebytes;
_connectionCount = connectionCount;
_isuserfuldata = isuserfuldata;
}
}
/// <summary>
/// socket发送数据Modle
/// </summary>
public class SendModle
{
#region 字段
/// <summary>
/// 用于发送对象的GUID
/// </summary>
private Guid _sendGuid;
/// <summary>
/// 用于控制发送开始和暂停
/// </summary>
private AutoResetEvent _controlevet;
/// <summary>
/// 发送命令的数组集合
/// </summary>
private List<byte[]> _sendcmd;
/// <summary>
/// 用于发送的Thread对象
/// </summary>
private Thread _sendthread;
/// <summary>
/// 当前执行到的命令索引
/// </summary>
private int _currentindex;
/// <summary>
/// 是否继续下发
/// </summary>
private bool _isuseful;

/// <summary>
/// 发送的命令
/// </summary>
private byte[] _sendbytes;
#endregion

#region 属性
/// <summary>
/// 用于发送对象的GUID
/// </summary>
public Guid SendGuid { get { return _sendGuid; } set { _sendGuid = value; } }
/// <summary>
/// 用于控制发送开始和暂停
/// </summary>
public AutoResetEvent Controlevet { get { return _controlevet; } set { _controlevet = value; } }
/// <summary>
/// 发送命令的数组集合
/// </summary>
public List<byte[]> Sendcmd { get { return _sendcmd; } set { _sendcmd = value; } }
/// <summary>
/// 用于发送的Thread对象
/// </summary>
public Thread Sendthread { get { return _sendthread; } set { _sendthread = value; } }
/// <summary>
/// 当前执行到的命令索引
/// </summary>
public int Currentindex { get { return _currentindex; } set { _currentindex = value; } }
/// <summary>
/// 发送的命令
/// </summary>
public byte[] Sendbytes { get { return _sendbytes; } set { _sendbytes = value; } }
/// <summary>
/// 是否继续下发
/// </summary>
public bool Isuseful { get { return _isuseful; } set { _isuseful = value; } }
#endregion

#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
public SendModle(Guid sendGuid, List<byte[]> Sendcmd)
{
_sendGuid = sendGuid;
_sendcmd = Sendcmd;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="sendGuid"></param>
/// <param name="Sendcmd"></param>
/// <param name="issendbyhand"></param>
public SendModle(Guid sendGuid, byte[] Sendbytes)
{
_sendGuid = sendGuid;
_sendbytes = Sendbytes;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="sendGuid">GUID唯一标识</param>
/// <param name="Sendcmd">定时下发的命令</param>
/// <param name="sendthread">定时下发命令线程</param>
/// <param name="currentindex"></param>
public SendModle(Guid sendGuid, AutoResetEvent controlevet, List<byte[]> Sendcmd, Thread sendthread, int currentindex, bool isuseful)
{
_sendGuid = sendGuid;
_controlevet = controlevet;
_sendcmd = Sendcmd;
_sendthread = sendthread;
_currentindex = currentindex;
_isuseful = isuseful;
}
#endregion
}
/// <summary>
/// UDP对象
/// </summary>
public class UDPModle
{
/// <summary>
/// ipendpoint 存放客户端Client Address和Port
/// </summary>
IPEndPoint _ipendpoint;
/// <summary>
/// ipendpoint 存放客户端Client Address和Port
/// </summary>
public IPEndPoint Ipendpoint { get { return _ipendpoint; } set { _ipendpoint = value; } }
/// <summary>
/// 上次接受数据时间
/// </summary>
DateTime _lastrecievedate;
/// <summary>
/// 上次接受数据时间
/// </summary>
public DateTime Lastrecievedate { get { return _lastrecievedate; } set { _lastrecievedate = value; } }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="ipendpoint"></param>
/// <param name="udpsocket"></param>
public UDPModle(IPEndPoint ipendpoint, DateTime lastrecievedate)
{
_ipendpoint = ipendpoint;
_lastrecievedate = lastrecievedate;
}
}

#endregion
}

posted on 2013-04-01 11:43  lanlongning  阅读(119)  评论(0)    收藏  举报