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();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|