1、TCP服务器实现代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PtLib.TcpServer
{
public delegate void TcpReceivedEventHandler(TcpStateEventArgs args);
public class TcpServer
{
#region 变量
//接收委托
public event TcpReceivedEventHandler TcpReceived;
//服务器IP
private string _ip = "127.0.0.1";
//服务器端口号
private int _port = 8080;
//当前Socket
Socket currentSocket = null;
//当前线程
Thread currentThread = null;
//Socket字典
public Dictionary<string,Socket> dictSocket = new Dictionary<string,Socket>();
//线程字典
public Dictionary<string,Thread> dictThread = new Dictionary<string,Thread>();
//运行标志
public bool isRun =false;
//
public bool isClientChanged = false;
#endregion
/// <summary>
/// 构造函数
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
public TcpServer(string ip,int port)
{
_ip = ip;
_port = port;
}
/// <summary>
/// 打开
/// </summary>
public void Open()
{
currentSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(_ip), _port);
currentSocket.Bind(endPoint);
currentSocket.Listen(10);
isRun = true;
currentThread = new Thread(WatchConnect);
currentThread.IsBackground = true;
currentThread.Start();
}
/// <summary>
/// 连接处理
/// </summary>
private void WatchConnect()
{
while (isRun)
{
Socket connectSocket=currentSocket.Accept();
dictSocket.Add(connectSocket.RemoteEndPoint.ToString(), connectSocket);
isClientChanged = true;
ParameterizedThreadStart pts = new ParameterizedThreadStart(Receiver);
Thread thread = new Thread(pts);
thread.IsBackground = true;
thread.Start(connectSocket);
dictThread.Add(connectSocket.RemoteEndPoint.ToString(), thread);
}
}
/// <summary>
/// 接收处理
/// </summary>
/// <param name="socketClientPara"></param>
private void Receiver(object socketClientPara)
{
Socket receiveSocket = socketClientPara as Socket;
while(true)
{
byte[] buffer = new byte[1024 * 1024];
int length = -1;
try
{
length = receiveSocket.Receive(buffer);
}catch(SocketException ex)
{
dictSocket.Remove(receiveSocket.RemoteEndPoint.ToString());
dictThread.Remove(receiveSocket.RemoteEndPoint.ToString());
isClientChanged = true;
Console.WriteLine(ex.Message);
break;
}catch(Exception ex)
{
Console.WriteLine(ex.Message);
break;
}
if (length > 0)
{
byte[] b = new byte[length];
Buffer.BlockCopy(buffer, 0, b, 0, length);
TcpStateEventArgs args = new TcpStateEventArgs();
args.ip = receiveSocket.RemoteEndPoint.ToString();
args.buffer = b;
TcpReceived?.Invoke(args);
}
}
}
/// <summary>
/// 发送
/// </summary>
/// <param name="ip"></param>
/// <param name="data"></param>
public void Send(string ip, byte[] data)
{
dictSocket[ip].Send(data);
}
/// <summary>
/// 关闭
/// </summary>
public void Close()
{
isRun = false;
Thread.Sleep(1000);
dictSocket.Clear();
dictThread.Clear();
if (currentSocket != null)
{
currentSocket.Close();
currentSocket = null;
}
if (currentThread.IsAlive)
{
currentThread.Abort();
}
currentThread = null;
}
}
/// <summary>
/// Tcp状态事件参数类
/// </summary>
public class TcpStateEventArgs : EventArgs
{
public string ip;
public byte[] buffer = null;
}
}
2、应用程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TcpServer
{
public partial class Form1 : Form
{
PtLib.TcpServer.TcpServer tcpServer= null;
Timer timer=new Timer();
/// <summary>
/// 构造函数
/// </summary>
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
timer.Interval = 1000;
timer.Tick += Timer_Tick;
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
if (tcpServer!=null && tcpServer.isClientChanged)
{
List<string> list = new List<string>();
foreach(var item in tcpServer.dictSocket.Keys)
{
list.Add(item);
}
this.Invoke(new Action(() =>
{
cbbClientIps.DataSource = list;
cbbClientIps.SelectedIndex = 0;
}));
tcpServer.isClientChanged = false;
}
}
/// <summary>
/// TCP服务器端打开或关闭
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btServerSwitch_Click(object sender, EventArgs e)
{
if(btServerSwitch.Text.Equals("打 开"))
{
btServerSwitch.Text = "关 闭";
string ip = tbServerIp.Text.Trim();
int port = int.Parse(tbServerPort.Text.Trim());
tcpServer = new PtLib.TcpServer.TcpServer(ip, port);
tcpServer.Open();
tcpServer.TcpReceived += TcpServer_TcpReceived;
}
else
{
btServerSwitch.Text = "打 开";
tcpServer.TcpReceived -= TcpServer_TcpReceived;
tcpServer.Close();
}
}
private void TcpServer_TcpReceived(PtLib.TcpServer.TcpStateEventArgs args)
{
string str = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")+":"+args.ip+",";
str += Encoding.UTF8.GetString(args.buffer);
this.Invoke(new Action(() =>
{
lbxReceive.Items.Add(str);
}));
}
/// <summary>
/// 数据发送
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
string ip= cbbClientIps.SelectedItem.ToString();
string str=tbSend.Text.Trim();
byte[] sendBytes = Encoding.UTF8.GetBytes(str);
tcpServer.Send(ip, sendBytes);
}
}
}
3、运行效果