using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StandardLibrary
{
///
/// TCP服务器类
///
class Tcp_Server
{
#region 字段声明
///
/// TCP服务器接收到客户端连接请求事件
///
public Action TcpConnectEvent;
///
/// TCP服务器接收到客户端发送消息事件
///
public Action TcpReceiveEvent;
///
/// 负责监听客户端连接请求的线程
///
private Thread threadWatch = null;
///
/// //服务器套接字
///
private Socket socketWatch = null;
///
/// //客户端IP与套接字的集合
///
private Dictionary dictSocket = new Dictionary();
///
/// //客户端IP与线程的集合
///
private Dictionary dictThread = new Dictionary();
private string _serverIp = "127.0.0.1";
private int _serverPort = 1234;
#endregion
public string ServerIp
{
get { return _serverIp; }
set { _serverIp = value; }
}
public int ServerPort
{
get { return _serverPort; }
set { _serverPort = value; }
}
///
/// 打开侦听
///
/// 侦听的IP
/// 侦听的端口号
public bool OpenTcpListen()
{
try
{
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建负责监听的套接字
IPAddress address = IPAddress.Parse(_serverIp);//获得IP地址
IPEndPoint endPoint = new IPEndPoint(address, _serverPort);//创建包含ip和端口号的网络节点对象
socketWatch.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
socketWatch.Bind(endPoint);//将负责监听的套接字绑定到唯一的ip和端口上
socketWatch.Listen(16);//设置侦听队列的长度,开始侦听
threadWatch = new Thread(WatchConnecting);//创建负责侦听的线程
threadWatch.IsBackground = true;//设置为后台线程
threadWatch.Start();//启动线程
return true;
}
catch (Exception e)
{
MessageBox.Show("异常:" + e.Message, "服务器侦听", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
return false;
}
}
///
/// 侦听客户端请求
///
private void WatchConnecting()
{
while (true) //持续监听客户端的连接请求
{
// 开始监听客户端连接请求,Accept方法会阻断当前的线程
Socket sokConnection = socketWatch.Accept(); //一旦监听到一个客户端的请求,就返回一个与该客户端通信的套接字
string ip = sokConnection.RemoteEndPoint.ToString().Split(':')[0];
if (!dictSocket.ContainsKey(ip)) dictSocket.Add(ip, sokConnection);//将客户端的IP对象添加到集合中
else dictSocket[ip] = sokConnection;
Thread thr = new Thread(ReceiveMsg);//创建处理客户端连接线程
thr.IsBackground = true;//设置为后台线程
thr.Start(sokConnection);//启动线程
if (!dictThread.ContainsKey(ip)) dictThread.Add(ip, thr); //将新建的线程添加到线程的集合中
else dictThread[ip] = thr;
if (TcpConnectEvent != null) TcpConnectEvent(ip, true);//发布客户端连接成功消息
}
}
///
/// 接收数据处理
///
/// 客户端套接字
private void ReceiveMsg(object sokConnectionparn)
{
Socket sokClient = sokConnectionparn as Socket;//客户端套接字
string ip = sokClient.RemoteEndPoint.ToString().Split(':')[0];
try
{
while (true)
{
byte[] arrMsgRec = new byte[2048 * 1];//定义一个1k字节的接收缓存区
int length = sokClient.Receive(arrMsgRec);//接收数据将数据存入arrMsgRec,返回数据的长度,并阻挡当前线程
if (length > 0)//判断接收到的数据长度,如果大于0则表示数据正常,如果小于或等于0则表示客户端断开连接
{
byte[] rec = new byte[length];
Array.Copy(arrMsgRec, rec, length);
if (TcpReceiveEvent != null) TcpReceiveEvent(ip, rec);//发布接收客户端消息
}
else dictThread[ip].Abort();//释放线程
}
}
catch (Exception)
{
if (dictSocket.ContainsKey(ip)) dictSocket.Remove(ip);//从通信套接字集合中删除被中断连接的通信套接字
if (dictThread.ContainsKey(ip)) dictThread.Remove(ip);//从通信线程集合中删除被中断连接的通信线程对象
if (TcpConnectEvent != null) TcpConnectEvent(ip, false);//发布客户端连接断开消息
}
}
public void CloseTcpConnect(string ip)
{
if (dictSocket.ContainsKey(ip))
{
dictThread[ip].Abort();
dictSocket[ip].Close();
}
}
public void CloseTcpListen()
{
//socketWatch.Close();
//socketWatch.Dispose();
//threadWatch.Abort();
}
///
/// 发送消息
///
/// 客户端IP地址
/// 数据
public bool SendServerMsg(string IP, string SendData)
{
try
{
byte[] sendMsg = Encoding.ASCII.GetBytes(SendData);
if (dictSocket.ContainsKey(IP)) dictSocket[IP].Send(sendMsg);//发送数据
return true;
}
catch { return false; }
}
///
/// 发送消息
///
/// 客户端IP地址
/// 数据
public bool SendServerMsg(string IP, byte[] SendData)
{
try
{
if (dictSocket.ContainsKey(IP)) dictSocket[IP].Send(SendData);//发送数据
return true;
}
catch { return false; }
}
}
///
/// TCP客户端类
///
class Tcp_Client
{
///
/// 接收消息事件
///
public event Action TcpReceiveEvent;
///
/// 连接状态事件
///
public event Action TcpConnectEvent;
///
/// TCP客户端
///
private Socket tcpClient;
///
/// 接收消息线程
///
private Thread receiveThread;
private string _ip = "127.0.0.1";
private int _port = 8500;
///
/// 获取或设置远程服务端IP地址
///
public string IP
{
get { return _ip; }
set { _ip = value; }
}
///
/// 获取或设置远程服务端端口号
///
public int Port
{
get { return _port; }
set { _port = value; }
}
///
/// 打开连接
///
///
///
public bool OpenTcpConnect()
{
IPEndPoint IpEnd = new IPEndPoint(IPAddress.Parse(_ip), _port);
tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
tcpClient.Connect(IpEnd);//发起TCP连接
receiveThread = new Thread(ReceiveMsg);//实例化并启动接受消息线程
receiveThread.IsBackground = true;//设置为后台线程
receiveThread.Start();//启动线程
if (TcpConnectEvent != null) TcpConnectEvent(true);//发布连接成功消息
return true;
}
catch (Exception e)
{
if (TcpConnectEvent != null) TcpConnectEvent(false);//发布连接失败消息
return false;
}
}
///
/// 关闭连接
///
public void CloseTcpConnect()
{
tcpClient.Close();//断开TCP连接
receiveThread.Abort();//销毁接受消息的线程
}
///
/// 接收服务端发送的消息
///
public void ReceiveMsg()
{
try
{
while (true)
{
byte[] getData = new byte[2048];//创建接受数据的字节流
int length = tcpClient.Receive(getData, getData.Length, 0);
if (length > 0)
{
byte[] rec = new byte[length];
Array.Copy(getData, rec, length);
string getMsg = Encoding.ASCII.GetString(rec);//将字节数组转换成文本形式
if (TcpReceiveEvent != null) TcpReceiveEvent(getMsg);
}
else receiveThread.Abort();//释放线程
}
}
catch (Exception e)//检测释放线程异常
{
if (TcpConnectEvent != null) TcpConnectEvent(false);//发布连接断开消息
CloseTcpConnect();
}
}
///
/// 发送消息给服务端
///
/// 数据
public void SendMsg(string msg)
{
byte[] sendData = Encoding.ASCII.GetBytes(msg);//将要发送的文本转换为字符数组形式
tcpClient.Send(sendData, sendData.Length, 0);
}
///
/// 发送消息给服务端
///
/// 数据
public void SendMsg(byte[] msg)
{
tcpClient.Send(msg);
}
}
}