1.类
(1)服务器端操作类
public class TcpServiceSocket
{
//接收数据事件
public Action<Socket, string> recvMessageEvent = null;
//发送结果事件
public Action<int> sendResultEvent = null;
//允许连接到tcp服务器的tcp客户端数量
private int numConnections = 0;
//连接socket
private Socket listenSocket = null;
//tcp服务器ip
private string host = "";
//tcp服务器端口
private int port = 0;
//控制tcp客户端连接数量的信号量
private Semaphore maxNumberAcceptedClients = null;
private int bufferSize = 1024;
private List<Socket> clientSockets = null;
public TcpServiceSocket(string host, int port, int numConnections)
{
if (string.IsNullOrEmpty(host))
throw new ArgumentNullException("host cannot be null");
if (port < 1 || port > 65535)
throw new ArgumentOutOfRangeException("port is out of range");
if (numConnections <= 0 || numConnections > int.MaxValue)
throw new ArgumentOutOfRangeException("_numConnections is out of range");
this.host = host;
this.port = port;
this.numConnections = numConnections;
clientSockets = new List<Socket>();
maxNumberAcceptedClients = new Semaphore(numConnections, numConnections);
}
public void Start()
{
try
{
listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(new IPEndPoint(IPAddress.Parse(host), port));
listenSocket.Listen(numConnections);
AcceptAsync();
}
catch (Exception)
{
}
}
private async void AcceptAsync()
{
await Task.Run(new Action(() =>
{
while (true)
{
maxNumberAcceptedClients.WaitOne();
try
{
Socket acceptSocket = listenSocket.Accept();
if (acceptSocket == null)
continue;
clientSockets.Add(acceptSocket);
RecvAsync(acceptSocket);
}
catch (Exception)
{
maxNumberAcceptedClients.Release();
}
}
}));
}
private async void RecvAsync(Socket acceptSocket)
{
await Task.Run(new Action(() =>
{
int len = 0;
byte[] buffer = new byte[bufferSize];
try
{
while ((len = acceptSocket.Receive(buffer, bufferSize, SocketFlags.None)) > 0)
{
if (recvMessageEvent != null)
recvMessageEvent(acceptSocket, Encoding.UTF8.GetString(buffer, 0, len));
}
}
catch (Exception)
{
CloseClientSocket(acceptSocket);
}
}));
}
public async void SendAsync(Socket acceptSocket, string message)
{
await Task.Run(new Action(() =>
{
int len = 0;
byte[] buffer = Encoding.UTF8.GetBytes(message);
try
{
if ((len = acceptSocket.Send(buffer, buffer.Length, SocketFlags.None)) > 0)
{
if (sendResultEvent != null)
sendResultEvent(len);
}
}
catch (Exception)
{
CloseClientSocket(acceptSocket);
}
}));
}
public async void SendMessageToAllClientsAsync(string message)
{
await Task.Run(new Action(() =>
{
foreach (var socket in clientSockets)
{
SendAsync(socket, message);
}
}));
}
private void CloseClientSocket(Socket acceptSocket)
{
try
{
acceptSocket.Shutdown(SocketShutdown.Both);
}
catch { }
try
{
acceptSocket.Close();
}
catch { }
maxNumberAcceptedClients.Release();
}
public void CloseAllClientSocket(Socket acceptSocket)
{
try
{
foreach (var socket in clientSockets)
{
socket.Shutdown(SocketShutdown.Both);
}
}
catch { }
try
{
foreach (var socket in clientSockets)
{
socket.Close();
}
}
catch { }
try
{
listenSocket.Shutdown(SocketShutdown.Both);
}
catch { }
try
{
listenSocket.Close();
}
catch { }
try
{
maxNumberAcceptedClients.Release(clientSockets.Count);
clientSockets.Clear();
}
catch { }
}
}
(2)客户端操作类
public class TcpClientSocket
{
//接收数据事件
public Action<string> recvMessageEvent = null;
//发送结果事件
public Action<int> sendResultEvent = null;
//连接socket
private Socket connectSocket = null;
//tcp服务器ip
private string host = "";
//tcp服务器端口
private int port = 0;
private int bufferSize = 1024;
public TcpClientSocket(string host, int port)
{
if (string.IsNullOrEmpty(host))
throw new ArgumentNullException("host cannot be null");
if (port < 1 || port > 65535)
throw new ArgumentOutOfRangeException("port is out of range");
this.host = host;
this.port = port;
}
public void Start()
{
try
{
connectSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connectSocket.Connect(host, port);
RecvAsync();
}
catch (Exception)
{
}
}
private async void RecvAsync()
{
await Task.Run(new Action(() =>
{
int len = 0;
byte[] buffer = new byte[bufferSize];
try
{
while ((len = connectSocket.Receive(buffer, bufferSize, SocketFlags.None)) > 0)
{
if (recvMessageEvent != null)
recvMessageEvent(Encoding.UTF8.GetString(buffer, 0, len));
}
}
catch (Exception)
{
Restart();
}
}));
}
public async void SendAsync(string message)
{
await Task.Run(new Action(() =>
{
int len = 0;
byte[] buffer = Encoding.UTF8.GetBytes(message);
try
{
if ((len = connectSocket.Send(buffer, buffer.Length, SocketFlags.None)) > 0)
{
if (sendResultEvent != null)
sendResultEvent(len);
}
}
catch (Exception)
{
Restart();
}
}));
}
public void CloseClientSocket()
{
try
{
connectSocket.Shutdown(SocketShutdown.Both);
}
catch { }
try
{
connectSocket.Close();
}
catch { }
}
public void Restart()
{
CloseClientSocket();
Start();
}
}
2.使用
(1)服务器:
public partial class Form1 : Form
{
TcpServiceSocket tcpServiceSocket = null;
private readonly string ip = "192.168.172.142";
private readonly int port = 8090;
public Form1()
{
InitializeComponent();
tcpServiceSocket = new TcpServiceSocket(ip, port, 10);
tcpServiceSocket.recvMessageEvent += new Action<Socket, string>(Recv);
}
private void Recv(Socket socket, string message)
{
this.BeginInvoke(new Action(() =>
{
tbRecv.Text += message + "
";
}));
}
private void btnStart_Click(object sender, EventArgs e)
{
tcpServiceSocket.Start();
}
private void btnSend_Click(object sender, EventArgs e)
{
string message = tbSend.Text.Trim();
if (string.IsNullOrEmpty(message))
return;
tcpServiceSocket.SendMessageToAllClientsAsync(message);
tbSend.Text = "";
}
}
(2)客户端
public partial class Form1 : Form
{
private TcpClientSocket tcpClientSocket = null;
private readonly string ip = "192.168.172.142";
private readonly int port = 8090;
public Form1()
{
InitializeComponent();
tcpClientSocket = new TcpClientSocket(ip, port);
tcpClientSocket.recvMessageEvent += new Action<string>(Recv);
}
private void Recv(string message)
{
this.BeginInvoke(new Action(() =>
{
tbRecv.Text += message + "
";
}));
}
private void btnStart_Click(object sender, EventArgs e)
{
tcpClientSocket.Start();
}
private void btnSend_Click(object sender, EventArgs e)
{
string message = tbSend.Text.Trim();
if (string.IsNullOrEmpty(message))
return;
tcpClientSocket.SendAsync(message);
tbSend.Text = "";
}
}