201 lines
6.9 KiB
C#
201 lines
6.9 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
using System.Net.Sockets;
|
||
using System.Net;
|
||
using System.Threading;
|
||
using UnityEngine;
|
||
|
||
namespace GeneralTools
|
||
{
|
||
public class TCPServer : SocketBase
|
||
{
|
||
Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
|
||
Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();
|
||
Thread threadWatch = null; // 负责监听客户端连接请求的 线程;
|
||
Socket socketWatch = null;
|
||
|
||
public TCPServer(string ip, int port, int _listenLong = 100)
|
||
{
|
||
InitSocket(ip, port, _listenLong);
|
||
}
|
||
|
||
//初始化
|
||
void InitSocket(string ip, int port, int _listenLong)
|
||
{
|
||
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||
IPAddress address = string.IsNullOrEmpty(ip) ? IPAddress.Any : IPAddress.Parse(ip);
|
||
IPEndPoint endPoint = new IPEndPoint(address, port);
|
||
try
|
||
{
|
||
socketWatch.Bind(endPoint);
|
||
}
|
||
catch (SocketException se)
|
||
{
|
||
Debug.LogError(se.Message);
|
||
return;
|
||
}
|
||
socketWatch.Listen(_listenLong);
|
||
threadWatch = new Thread(WatchConnecting);
|
||
threadWatch.IsBackground = true;
|
||
threadWatch.Start();
|
||
}
|
||
void WatchConnecting()
|
||
{
|
||
while (true) // 持续不断的监听客户端的连接请求;
|
||
{
|
||
if (socketClose)
|
||
return;
|
||
// 开始监听客户端连接请求,Accept方法会阻断当前的线程;
|
||
Socket sokConnection = null;
|
||
try
|
||
{
|
||
sokConnection = socketWatch.Accept();
|
||
}
|
||
catch (SocketException)
|
||
{
|
||
continue;
|
||
}
|
||
if (sokConnection == null)
|
||
continue;
|
||
// 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字;
|
||
// 想列表控件中添加客户端的IP信息
|
||
// 将与客户端连接的 套接字 对象添加到集合中;
|
||
dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);
|
||
Thread thr = new Thread(RecMsg);
|
||
thr.IsBackground = true;
|
||
thr.Start(sokConnection);
|
||
dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); // 将新建的线程 添加 到线程的集合中去。
|
||
}
|
||
}
|
||
void RecMsg(object sokConnectionparn)
|
||
{
|
||
Socket sokClient = sokConnectionparn as Socket;
|
||
string remoteEndPoint = sokClient.RemoteEndPoint.ToString();
|
||
while (true)
|
||
{
|
||
if (socketClose)
|
||
return;
|
||
byte[] arrMsgRec = new byte[reveiceByteSize];
|
||
// 将接受到的数据存入到输入 arrMsgRec中;
|
||
int length = -1;
|
||
try
|
||
{
|
||
length = sokClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
// 从 通信套接字 集合中删除被中断连接的通信套接字;
|
||
dict.Remove(remoteEndPoint);
|
||
// 从通信线程集合中删除被中断连接的通信线程对象;
|
||
dictThread.Remove(remoteEndPoint);
|
||
// 从列表中移除被中断的连接IP
|
||
break;
|
||
}
|
||
if (length == 0)
|
||
{
|
||
// 从 通信套接字 集合中删除被中断连接的通信套接字;
|
||
dict.Remove(remoteEndPoint);
|
||
// 从通信线程集合中删除被中断连接的通信线程对象;
|
||
dictThread.Remove(remoteEndPoint);
|
||
// 从列表中移除被中断的连接IP
|
||
break;
|
||
}
|
||
//保存接收到的数据
|
||
RecordReceiveMsg(arrMsgRec, length, sokClient.LocalEndPoint, sokClient.RemoteEndPoint);
|
||
}
|
||
}
|
||
public override void SendMsg(string strMsg)
|
||
{
|
||
byte[] _sendData = String2Bytes(strMsg, encoding);
|
||
foreach (Socket s in dict.Values)
|
||
{
|
||
try
|
||
{
|
||
s.Send(_sendData, _sendData.Length, SocketFlags.None);
|
||
}
|
||
catch (Exception se)
|
||
{
|
||
Debug.LogError(se.Message);
|
||
}
|
||
}
|
||
}
|
||
public override void SendMsg(byte[] byteMsg)
|
||
{
|
||
base.SendMsg(byteMsg);
|
||
foreach (Socket s in dict.Values)
|
||
{
|
||
try
|
||
{
|
||
s.Send(byteMsg, byteMsg.Length, SocketFlags.None);
|
||
}
|
||
catch (Exception se)
|
||
{
|
||
Debug.LogError(se.Message);
|
||
}
|
||
}
|
||
}
|
||
public override void SendMsg(IPEndPoint remote, string strMsg)
|
||
{
|
||
base.SendMsg(remote, strMsg);
|
||
byte[] _sendData = String2Bytes(strMsg, encoding);
|
||
string remoteStr = remote.ToString();
|
||
if (dict.ContainsKey(remoteStr))
|
||
{
|
||
try
|
||
{
|
||
dict[remoteStr].Send(_sendData, _sendData.Length, SocketFlags.None);
|
||
}
|
||
catch (Exception se)
|
||
{
|
||
Debug.LogError(se.Message);
|
||
}
|
||
}
|
||
}
|
||
public override void SendMsg(IPEndPoint remote, byte[] byteMsg)
|
||
{
|
||
base.SendMsg(remote, byteMsg);
|
||
string remoteStr = remote.ToString();
|
||
if (dict.ContainsKey(remoteStr))
|
||
{
|
||
try
|
||
{
|
||
dict[remoteStr].Send(byteMsg, byteMsg.Length, SocketFlags.None);
|
||
}
|
||
catch (Exception se)
|
||
{
|
||
Debug.LogError(se.Message);
|
||
}
|
||
}
|
||
}
|
||
//连接关闭
|
||
public override void SocketQuit()
|
||
{
|
||
base.SocketQuit();
|
||
foreach (var dic in dict)
|
||
{
|
||
if (dic.Value != null)
|
||
{
|
||
dic.Value.Close();
|
||
}
|
||
}
|
||
|
||
foreach (var dic in dictThread)
|
||
{
|
||
if (dic.Value != null)
|
||
{
|
||
dic.Value.Interrupt();
|
||
dic.Value.Abort();
|
||
}
|
||
}
|
||
if (socketWatch != null)
|
||
socketWatch.Close();
|
||
|
||
if (threadWatch != null)
|
||
{
|
||
threadWatch.Interrupt();
|
||
threadWatch.Abort();
|
||
}
|
||
}
|
||
}
|
||
} |