using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace TcpipConnect
{
public class TcpIpSocketSever : TcpipSever.ICommunicatTcpipSever
{
#region 公共委托
///
/// 接收数据事件
///
public event TcpipSever.ReceiveDataEventHandler ReceiveDataEvent;
#endregion
#region 公共事件
///
/// 客户端已连接事件
///
public event TcpipSever.HasClientToConnectEventHandler HasClientToConnectEvent;
///
/// 客户端断开连接事件
///
public event TcpipSever.ClientToDisConnectEventHandler ClientToDisConnectEvent;
#endregion
#region 私有属性
///
/// 声明套接字接口
///
private static Socket _Socket;
///
/// 读取缓冲区尺寸
///
private static int _ReceiveBufferSize = 100;
///
/// 存储已连接的客户端的泛型集合
///
private Dictionary
#endregion
#region 公共访问器
///
/// 存储已连接的客户端的泛型集合
///
public Dictionary
{
get { return _socketList; }
set { _socketList = value; }
}
///
/// 监视开启
///
public bool IsMonitorOpen { get; set; }
///
/// 服务器IP
///
public string SeverIp { get; set; }
///
/// 服务器端口号
///
public int Dstport { get; set; }
///
/// 缓冲区尺寸
///
public int ReceiveBufferSize
{
get { return _ReceiveBufferSize; }
set { _ReceiveBufferSize = value; }
}
#endregion
public TcpIpSocketSever()
{
}
#region 公共方法
///
/// 监听开
///
/// IP地址
/// 端口号
/// 监控开始委托
///
public Err MonitorOpen(string ip, int dstPort, TcpipSever.DelegateMonitorStart monitorStart)
{
Err err = new Err();
try
{
//实例化一个Socket对象,确定网络类型、Socket类型、协议类型
_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
IPEndPoint IEP = new IPEndPoint(IPAddress.Parse(ip), int.Parse(dstPort.ToString()));
//绑定ip和端口
_Socket.Bind(IEP);
//开启监听
_Socket.Listen(10);
//监视开始委托
monitorStart(DateTime.Now);
SeverIp = ip;
Dstport = dstPort;
Thread thread = new Thread(new ParameterizedThreadStart(StartServer));
thread.IsBackground = true;
thread.Start(_Socket);
return err;
}
catch (Exception ex)
{
err.Msg = ex.Message;
err.isErr = true;
return err;
}
}
///
/// 监视停止
///
public Err MonitorClose()
{
Err err = new Err();
try
{
//关闭监视线程
IsMonitorOpen = false;
if (_Socket == null)
return err = new Err() { isErr = true,Msg="socket为空返回" };
if (!_Socket.Connected)
return err = new Err() { isErr = true, Msg = "socket已关闭不需要再次操作" };
_Socket.Shutdown(SocketShutdown.Both);
_Socket.Close();
return err;
}
catch (Exception ex)
{
err.Msg = ex.Message;
err.isErr = true;
return err;
}
}
///
/// 发送数据
///
/// 发送数据
/// 客户端
/// 发送数据完成委托
///
public Err Send(string msg, string client, TcpipSever.DelegateSendData sendData)
{
Err err = new Err();
try
{
//发送消息为空则返回
if (msg.Trim() == "")
{
return err = new Err() { isErr = true, Msg = "发送消息不能为空" };
}
//如果不存在客户端KEY则返回
if (!_socketList.ContainsKey(client))
{
return err = new Err() { isErr = true, Msg = "不存在此客户端" };
}
//获取发送数据的BYTE位集合
byte[] bytes = Encoding.Default.GetBytes(msg);
//发送数据
_socketList[client].Send(bytes);
//发送数据完成委托
if (sendData != null) sendData(msg, client, DateTime.Now);
return err;
}
catch (Exception ex)
{
err.Msg = ex.Message;
err.isErr = true;
return err;
}
}
#endregion
#region 私有方法
///
/// 接收连接
///
///
private void StartServer(object obj)
{
string str;
IsMonitorOpen = true;
while (IsMonitorOpen)
{
//等待接收客户端连接 Accept方法返回一个用于和该客户端通信的Socket
Socket recviceSocket = ((Socket)obj).Accept();
//获取客户端ip和端口号
str = recviceSocket.RemoteEndPoint.ToString();
_socketList.Add(str, recviceSocket);
if(HasClientToConnectEvent!=null)
//刷新客户端连接事件
HasClientToConnectEvent(_socketList, str, DateTime.Now);
//Accept()执行过后 当前线程会阻塞 只有在有客户端连接时才会继续执行
//创建新线程,监控接收新客户端的请求数据
Thread thread = new Thread(startRecive);
thread.IsBackground = true;
thread.Start(recviceSocket);
}
}
///
/// 接收消息
///
/// 客户端socket
private void startRecive(object obj)
{
string str;
string ip;
int readCount = 0;
while (IsMonitorOpen)
{
byte[] buffer = new byte[ReceiveBufferSize];
int count;
try
{
//Receive(Byte[]) 从绑定的 Socket 套接字接收数据,将数据存入接收缓冲区。
//该方法执行过后同Accept()方法一样 当前线程会阻塞 等到客户端下一次发来数据时继续执行
count = ((Socket)obj).Receive(buffer);
ip = ((Socket)obj).RemoteEndPoint.ToString();
if (count == 0)
{
_socketList.Remove(ip);
if (ClientToDisConnectEvent!=null)
ClientToDisConnectEvent(_socketList, ip, DateTime.Now);
break;
}
else
{
str = Encoding.Default.GetString(buffer, 0, count).Replace("\r", "").Replace("\n", "");
readCount++;
if (ReceiveDataEvent != null)
ReceiveDataEvent(str, ip, DateTime.Now);
}
}
catch (Exception)
{
}
}
}
#endregion
}
}