diff --git a/SocketStudy.ClientApp/App.xaml b/SocketStudy.ClientApp/App.xaml
new file mode 100644
index 0000000..c88a47c
--- /dev/null
+++ b/SocketStudy.ClientApp/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/SocketStudy.ClientApp/App.xaml.cs b/SocketStudy.ClientApp/App.xaml.cs
new file mode 100644
index 0000000..be11afa
--- /dev/null
+++ b/SocketStudy.ClientApp/App.xaml.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace SocketStudy.ClientApp
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+}
diff --git a/SocketStudy.ClientApp/AssemblyInfo.cs b/SocketStudy.ClientApp/AssemblyInfo.cs
new file mode 100644
index 0000000..8b5504e
--- /dev/null
+++ b/SocketStudy.ClientApp/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/SocketStudy.ClientApp/Images/logo.ico b/SocketStudy.ClientApp/Images/logo.ico
new file mode 100644
index 0000000..4159cd4
Binary files /dev/null and b/SocketStudy.ClientApp/Images/logo.ico differ
diff --git a/SocketStudy.ClientApp/Images/logo.red.ico b/SocketStudy.ClientApp/Images/logo.red.ico
new file mode 100644
index 0000000..411b3b3
Binary files /dev/null and b/SocketStudy.ClientApp/Images/logo.red.ico differ
diff --git a/SocketStudy.ClientApp/MainWindow.xaml b/SocketStudy.ClientApp/MainWindow.xaml
new file mode 100644
index 0000000..c385cd2
--- /dev/null
+++ b/SocketStudy.ClientApp/MainWindow.xaml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SocketStudy.ClientApp/MainWindow.xaml.cs b/SocketStudy.ClientApp/MainWindow.xaml.cs
new file mode 100644
index 0000000..7e7ddad
--- /dev/null
+++ b/SocketStudy.ClientApp/MainWindow.xaml.cs
@@ -0,0 +1,273 @@
+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;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace SocketStudy.ClientApp
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ private TcpClient _tcpClient;
+
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+
+
+ ///
+ /// 连接服务网络
+ ///
+ private void btn_Connect_Click(object sender, RoutedEventArgs e)
+ {
+ if (_tcpClient?.Connected ?? false)
+ {
+ WriteLog("已经连接上!");
+ return;
+ }
+
+ IPAddress serverAddress;
+ if (!IPAddress.TryParse(textBox_ServerAddress.Text.Trim(), out serverAddress))
+ {
+ WriteLog("服务地址错误");
+ return;
+ }
+
+ int serverPort = 6605;
+ if (!int.TryParse(textBox_ServerPort.Text.Trim(), out serverPort))
+ {
+ WriteLog("服务器端口号错误");
+ return;
+ }
+ else
+ {
+ if (serverPort <= 1024 || serverPort >= 65535)
+ {
+ WriteLog("服务器端口号错误:必须在 1205-65534");
+ return;
+ }
+ }
+ IPEndPoint serverEndPoint = new IPEndPoint(serverAddress, serverPort);
+
+ IPAddress clientAddress;
+ if (!IPAddress.TryParse(textBox_ClientAddress.Text.Trim(), out clientAddress))
+ {
+ WriteLog("本地连接地址错误");
+ return;
+ }
+ int clientPort = 6901;
+ if (!int.TryParse(textBox_ClientPort.Text.Trim(), out clientPort))
+ {
+ WriteLog("本地连接端口号错误");
+ return;
+ }
+ else
+ {
+ if (clientPort <= 1024 || clientPort >= 65535)
+ {
+ WriteLog("本地连接端口号错误:必须在 1205-65534");
+ return;
+ }
+ }
+ IPEndPoint clientEndPoint = new IPEndPoint(clientAddress, clientPort);
+
+ if (_tcpClient != null)
+ {
+ _tcpClient?.Dispose();
+ _tcpClient = null;
+ }
+
+ try
+ {
+ _tcpClient = new TcpClient(clientEndPoint);
+ _tcpClient.LingerState = new LingerOption(true, 0);
+ //_tcpClient.SendTimeout = 10000;
+ //_tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ _tcpClient.Connect(serverEndPoint);
+
+ textBox_ServerAddress.IsEnabled = false;
+ textBox_ServerPort.IsEnabled = false;
+ textBox_ClientPort.IsEnabled = false;
+
+ WriteLog("连接到服务器,成功");
+
+ //接收服务端发来的数据
+ ThreadPool.QueueUserWorkItem(obj =>
+ {
+ try
+ {
+ do
+ {
+ NetworkStream streamToClient = _tcpClient.GetStream();
+ if (streamToClient.CanRead && streamToClient.DataAvailable)
+ {
+ byte[] buffer = new byte[8096];
+ var readCount = streamToClient.Read(buffer, 0, buffer.Length);
+ if (readCount <= 0)
+ {
+ break;
+ }
+ var message = Encoding.UTF8.GetString(buffer, 0, readCount);
+
+ WriteLog($"接收到数据:{message}");
+
+ }
+ else
+ {
+ //WriteLog($"接收到无用数据包");
+ }
+ }
+ while (_tcpClient.Connected);
+ }
+ catch (Exception ex)
+ {
+
+ }
+ finally
+ {
+
+ }
+
+ });
+
+ WriteLog($"连接操作执行完成,数据接收线程已启动!");
+ }
+ catch (SocketException socketException)
+ {
+ WriteLog($"连接到服务器时,异常:{socketException.Message}");
+ }
+ catch (Exception ex)
+ {
+ WriteLog($"连接到服务器时,异常:{ex.Message}");
+ }
+ finally
+ {
+
+ }
+ }
+
+ ///
+ /// 关闭网络连接
+ ///
+ private void btn_Close_Click(object sender, RoutedEventArgs e)
+ {
+ if (_tcpClient == null || _tcpClient.Connected == false)
+ {
+ WriteLog("网络未连接到服务器,无需关闭!");
+ return;
+ }
+
+ _tcpClient.GetStream().Close();
+ //_tcpClient.GetStream().Dispose();
+ _tcpClient.Close();
+
+ _tcpClient.Client?.Disconnect(false);
+
+ _tcpClient.Dispose();
+
+
+
+ textBox_ServerAddress.IsEnabled = true;
+ textBox_ServerPort.IsEnabled = true;
+ textBox_ClientPort.IsEnabled = true;
+
+ WriteLog($"连接已成功关闭!");
+ }
+
+ ///
+ /// 使用连接,发送数据给服务器
+ ///
+ private void btn_Send_Click(object sender, RoutedEventArgs e)
+ {
+ if (_tcpClient == null)
+ {
+ WriteLog("网络连接不存在,请先连接到网络服务器!");
+ return;
+ }
+
+ if (!_tcpClient.Connected)
+ {
+ WriteLog("请先连接到网络服务器!");
+ return;
+ }
+
+ try
+ {
+ var message = textBox_SendData.Text.Trim();
+ byte[] buffer = Encoding.UTF8.GetBytes(message);
+ NetworkStream networkStream = _tcpClient.GetStream();
+ networkStream.Write(buffer, 0, buffer.Length);
+ WriteLog($"数据发送成功:{message}");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"{ex.Message}");
+ WriteLog($"{ex.Message}");
+ }
+ finally
+ {
+
+ }
+ }
+
+ ///
+ /// 释放连接
+ ///
+
+ private void btn_Dispose_Click(object sender, RoutedEventArgs e)
+ {
+ if (_tcpClient == null)
+ {
+ WriteLog("网络未连接到服务器,无需释放!");
+ return;
+ }
+
+ if (_tcpClient.Connected)
+ {
+ //_tcpClient.GetStream().Close();
+ _tcpClient.Client?.Disconnect(true);
+ _tcpClient.Close();
+ WriteLog("关闭连接成功!");
+ }
+
+
+ _tcpClient.Dispose();
+
+
+ textBox_ServerAddress.IsEnabled = true;
+ textBox_ServerPort.IsEnabled = true;
+ textBox_ClientPort.IsEnabled = true;
+
+ WriteLog("连接已成功释放!");
+ }
+
+ ///
+ /// 写日志信息
+ ///
+ private void WriteLog(string message)
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ richTextBox_Log.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} {message}{System.Environment.NewLine}");
+ richTextBox_Log.ScrollToEnd();
+ Console.WriteLine(message);
+ }));
+ }
+ }
+}
diff --git a/SocketStudy.ClientApp/SocketStudy.ClientApp.csproj b/SocketStudy.ClientApp/SocketStudy.ClientApp.csproj
new file mode 100644
index 0000000..5097e91
--- /dev/null
+++ b/SocketStudy.ClientApp/SocketStudy.ClientApp.csproj
@@ -0,0 +1,24 @@
+
+
+
+ WinExe
+ net6.0-windows
+ enable
+ true
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
diff --git a/SocketStudy.ServerApp/App.xaml b/SocketStudy.ServerApp/App.xaml
new file mode 100644
index 0000000..c8e0fc9
--- /dev/null
+++ b/SocketStudy.ServerApp/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/SocketStudy.ServerApp/App.xaml.cs b/SocketStudy.ServerApp/App.xaml.cs
new file mode 100644
index 0000000..deb71d3
--- /dev/null
+++ b/SocketStudy.ServerApp/App.xaml.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace SocketStudy.ServerApp
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+}
diff --git a/SocketStudy.ServerApp/AssemblyInfo.cs b/SocketStudy.ServerApp/AssemblyInfo.cs
new file mode 100644
index 0000000..8b5504e
--- /dev/null
+++ b/SocketStudy.ServerApp/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/SocketStudy.ServerApp/Images/logo.ico b/SocketStudy.ServerApp/Images/logo.ico
new file mode 100644
index 0000000..0b9f124
Binary files /dev/null and b/SocketStudy.ServerApp/Images/logo.ico differ
diff --git a/SocketStudy.ServerApp/MainWindow.xaml b/SocketStudy.ServerApp/MainWindow.xaml
new file mode 100644
index 0000000..664025a
--- /dev/null
+++ b/SocketStudy.ServerApp/MainWindow.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SocketStudy.ServerApp/MainWindow.xaml.cs b/SocketStudy.ServerApp/MainWindow.xaml.cs
new file mode 100644
index 0000000..0814cc1
--- /dev/null
+++ b/SocketStudy.ServerApp/MainWindow.xaml.cs
@@ -0,0 +1,382 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+using System.Net;
+using System.Net.Http;
+using System.Net.Sockets;
+using System.Threading;
+
+namespace SocketStudy.ServerApp
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ //服务监听
+ private TcpListener _tcpServer = null;
+
+ //存放活动客户端连接字典
+ private ConcurrentDictionary _remoteClientDic = new ConcurrentDictionary();
+
+ //监听线程
+ private Thread _listenerThread;
+
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// 窗口呈现完毕事件
+ ///
+ private void Window_ContentRendered(object sender, EventArgs e)
+ {
+ //初始化客户端
+ comboBox_Clients.Items.Clear();
+ comboBox_Clients.Items.Insert(insertIndex: 0,"广播");
+ comboBox_Clients.SelectedIndex = 0;
+
+ //默认服务器网址
+ comboBox_ServerAddress.Items.Insert(0, "本机所有IP4");
+ comboBox_ServerAddress.SelectedIndex = 0;
+
+ var ip4Addresses = Dns.GetHostAddresses(Dns.GetHostName(), AddressFamily.InterNetwork) ?? new IPAddress[] { IPAddress.Any};
+ foreach (var ip in ip4Addresses)
+ {
+ comboBox_ServerAddress.Items.Add(ip);
+ }
+ }
+
+ ///
+ /// 启动服务
+ ///
+ private void btn_Start_Click(object sender, RoutedEventArgs e)
+ {
+ if (_tcpServer?.Server?.IsBound ?? false)
+ {
+ WriteLog("服务正在运行,无需启动!");
+ return;
+ }
+
+ IPAddress serverAddress = IPAddress.Any;
+
+ if (comboBox_ServerAddress.SelectedValue.ToString() != "本机所有IP4")
+ {
+ serverAddress = (IPAddress)comboBox_ServerAddress.SelectedValue;
+ }
+
+ int serverPort = 6605;
+ if (!int.TryParse(textBox_ServerPort.Text.Trim(), out serverPort))
+ {
+ WriteLog("端口号错误");
+ return;
+ }
+ else
+ {
+ if (serverPort <= 1024 || serverPort >= 65535)
+ {
+ WriteLog("端口号错误:必须在 1205-65534");
+ return;
+ }
+ }
+
+ WriteLog("启动服务...");
+ _tcpServer = new TcpListener(serverAddress, serverPort);
+ _tcpServer.Start();
+
+ WriteLog("服务成功启动!");
+
+ //开启监听线程
+ _listenerThread = new Thread(AcceptTcpClient);
+ _listenerThread.IsBackground = true;
+ _listenerThread.Start(_tcpServer);
+
+ //控件操作
+ comboBox_ServerAddress.IsEnabled = false;
+ textBox_ServerPort.IsEnabled = false;
+
+ WriteLog("服务启动完毕!");
+ }
+
+ ///
+ /// 停止服务
+ ///
+ private void btn_Stop_Click(object sender, RoutedEventArgs e)
+ {
+ if (_tcpServer == null || _tcpServer.Server.IsBound == false)
+ {
+ WriteLog("服务正未运行,无法停止!");
+ return;
+ }
+
+ //关闭客户端
+ foreach (var item in _remoteClientDic)
+ {
+ if (item.Value.Connected)
+ {
+ item.Value.Close();
+ item.Value.Dispose();
+ }
+ }
+
+ WriteLog("停止服务...");
+ _tcpServer?.Stop();
+
+ //清空客户端
+ _remoteClientDic.Clear();
+ ResetClientsItems();
+
+
+ //恢复控制状态
+ comboBox_ServerAddress.IsEnabled = true;
+ textBox_ServerPort.IsEnabled = true;
+
+ WriteLog("服务停止完成!");
+ }
+
+ ///
+ /// 发送数据
+ ///
+ private void btn_Send_Click(object sender, RoutedEventArgs e)
+ {
+ if (_remoteClientDic.Count == 0 || comboBox_Clients.Items.Count ==0)
+ {
+ WriteLog("没有正在连接的客户端,请先使用客户端连接到本服务器!");
+ return;
+ }
+
+ var clientForSend=new List();
+
+ var selectedItemValue = comboBox_Clients.SelectedValue as string;
+ if (selectedItemValue == "广播")
+ {
+ clientForSend = _remoteClientDic.Where(q => q.Value.Connected == true).Select(d => d.Value).ToList();
+ }
+ else
+ {
+ var queryItem = _remoteClientDic.FirstOrDefault(q => q.Key == comboBox_Clients.SelectedValue.ToString());
+
+ clientForSend.Add(queryItem.Value);
+ }
+
+ foreach (var client in clientForSend)
+ {
+ try
+ {
+ var message = textBox_SendData.Text.Trim();
+ byte[] buffer = Encoding.UTF8.GetBytes(message);
+ NetworkStream networkStream = client.GetStream();
+ networkStream.Write(buffer, 0, buffer.Length);
+
+ WriteLog($"发送数据成功:{message}");
+ }
+ catch (Exception ex)
+ {
+ WriteLog($"{ex.Message}");
+ }
+ finally
+ {
+
+ }
+ }
+ }
+
+ ///
+ /// 写日志信息
+ ///
+ private void WriteLog(string message)
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ richTextBox_Log.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} {message}{System.Environment.NewLine}");
+ richTextBox_Log.ScrollToEnd();
+ Console.WriteLine(message);
+ }));
+ }
+
+ ///
+ /// 重新设置客户端列表项
+ ///
+ private void ResetClientsItems()
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ //字典中的远程客户端同步到下拉列表项
+ foreach (var clientItem in _remoteClientDic)
+ {
+ if (!comboBox_Clients.Items.Contains(clientItem.Key))
+ {
+ comboBox_Clients.Items.Add(clientItem.Key);
+ }
+ }
+
+ //从下拉项中移除已经下线的远程客户端
+ for (int i = 0; i < comboBox_Clients.Items.Count; i++)
+ {
+ var itemValue = comboBox_Clients.Items[i] as string;
+
+ if (itemValue == null)
+ {
+ continue;
+ }
+
+ if (itemValue.Contains("广播"))
+ {
+ continue;
+ }
+
+ if (!_remoteClientDic.ContainsKey(itemValue))
+ {
+ comboBox_Clients.Items.Remove(comboBox_Clients.Items[i]);
+ }
+ }
+ }));
+ }
+
+ ///
+ /// 监听客户端连接方法
+ ///
+ private void AcceptTcpClient(Object? tcpListener)
+ {
+ TcpListener? tcpServer = tcpListener as TcpListener;
+
+ if (tcpServer == null)
+ {
+ WriteLog("调用监听连接方法时,参数为null,将监听不到客户端连接!");
+ return;
+ }
+
+ WriteLog("开始监听客户端连接...");
+ //无限循环:处理多个客户端连接
+ while (_tcpServer.Server.IsBound)
+ {
+ TcpClient remoteClientSocket = null;
+ try
+ {
+ //阻塞等待操作
+ remoteClientSocket = _tcpServer.AcceptTcpClient();
+ WriteLog("接收到连接请求...");
+
+ var remoteEndPoint = remoteClientSocket.Client.RemoteEndPoint as IPEndPoint;
+ if (remoteEndPoint == null)
+ {
+ continue;
+ }
+
+ string ipAndPortKey = $"{remoteEndPoint.Address}:{remoteEndPoint.Port}";
+
+ if (!_remoteClientDic.ContainsKey(ipAndPortKey))
+ {
+ _remoteClientDic.TryAdd(ipAndPortKey, remoteClientSocket);
+ }
+
+ ResetClientsItems();
+
+ //接收数据线程
+ Thread receviceThread = new Thread(ReciveData);
+ receviceThread.IsBackground = true;
+ receviceThread.Start(remoteClientSocket);
+
+ WriteLog("连接请求处理完成!");
+ }
+ catch (SocketException socketException)
+ {
+ //移除客户端
+ remoteClientSocket?.Close();
+ remoteClientSocket?.Dispose();
+
+ WriteLog($"出现Socket异常:{socketException.Message}");
+ }
+ catch (Exception ex)
+ {
+ //移除客户端
+ remoteClientSocket?.Close();
+ remoteClientSocket?.Dispose();
+
+ WriteLog($"出现异常:{ex.Message}");
+ }
+ finally
+ {
+ }
+ }
+
+ //清空客户端
+ _remoteClientDic.Clear();
+ ResetClientsItems();
+
+ WriteLog($"监听客户端连接的线程,退出!线程托管Id={Thread.CurrentThread.ManagedThreadId}");
+ }
+
+ ///
+ /// 接收客户端数据方法
+ ///
+ private void ReciveData(object? tcpClient)
+ {
+ if (tcpClient == null)
+ {
+ WriteLog($"接收数据出错:客户端参数{nameof(tcpClient)}为 null");
+ return;
+ }
+
+ TcpClient remoteClient = (TcpClient)tcpClient;
+ IPEndPoint? remoteEndPoint = remoteClient.Client?.RemoteEndPoint as IPEndPoint;
+ string remoteClientKey = $"{remoteEndPoint?.Address}:{remoteEndPoint?.Port}";
+
+ try
+ {
+ while (remoteClient.Connected)
+ {
+ NetworkStream remoteClientStream = remoteClient.GetStream();
+ byte[] buffer = new byte[8096];
+
+ //阻塞等待操作
+ var readCount = remoteClientStream.Read(buffer, 0, buffer.Length);
+
+ //为0代表客户端主动发送关闭操作数据。平常时,即使发送0长度数据也不会是0
+ if (readCount == 0)
+ {
+ remoteClientStream.Close();
+ remoteClientStream.Dispose();
+
+ WriteLog($"接收[{remoteClientKey}]关闭连接请求数据。");
+ break;
+ }
+ var message = Encoding.UTF8.GetString(buffer, 0, readCount);
+ WriteLog($"接收到[{remoteClientKey}]数据:{message}");
+ }
+ }
+ catch (SocketException socketException)
+ {
+ WriteLog($"接收到[{remoteClientKey}]数据异常:{socketException.Message}");
+ }
+ catch (Exception ex)
+ {
+ WriteLog($"接收到[{remoteClientKey}]数据异常:{ex.Message}");
+ }
+ finally
+ {
+ remoteClient.Close();
+ remoteClient.Dispose();
+
+ _remoteClientDic.Remove(remoteClientKey, out var sss);
+ ResetClientsItems();
+
+ WriteLog($"接收[{remoteClientKey}]数据的线程退出:线程托管Id={Thread.CurrentThread.ManagedThreadId}");
+ }
+ }
+ }
+}
diff --git a/SocketStudy.ServerApp/SocketStudy.ServerApp.csproj b/SocketStudy.ServerApp/SocketStudy.ServerApp.csproj
new file mode 100644
index 0000000..0b9fd24
--- /dev/null
+++ b/SocketStudy.ServerApp/SocketStudy.ServerApp.csproj
@@ -0,0 +1,20 @@
+
+
+
+ WinExe
+ net6.0-windows
+ enable
+ true
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/SocketStudy.sln b/SocketStudy.sln
new file mode 100644
index 0000000..bb47e5b
--- /dev/null
+++ b/SocketStudy.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.2.32519.379
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SocketStudy.ServerApp", "SocketStudy.ServerApp\SocketStudy.ServerApp.csproj", "{728CF602-AF27-4450-B042-C1D7996ED6A2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SocketStudy.ClientApp", "SocketStudy.ClientApp\SocketStudy.ClientApp.csproj", "{ED05BC97-29C5-443E-A30D-6F3DC0F8F81F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SocketStudyTest", "SocketStudyTest\SocketStudyTest.csproj", "{AB061217-61AE-4687-91D2-7A14EFD16FCF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {728CF602-AF27-4450-B042-C1D7996ED6A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {728CF602-AF27-4450-B042-C1D7996ED6A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {728CF602-AF27-4450-B042-C1D7996ED6A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {728CF602-AF27-4450-B042-C1D7996ED6A2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ED05BC97-29C5-443E-A30D-6F3DC0F8F81F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ED05BC97-29C5-443E-A30D-6F3DC0F8F81F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ED05BC97-29C5-443E-A30D-6F3DC0F8F81F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ED05BC97-29C5-443E-A30D-6F3DC0F8F81F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB061217-61AE-4687-91D2-7A14EFD16FCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB061217-61AE-4687-91D2-7A14EFD16FCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB061217-61AE-4687-91D2-7A14EFD16FCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB061217-61AE-4687-91D2-7A14EFD16FCF}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {5BC40834-E7D0-4639-B789-40226A913F55}
+ EndGlobalSection
+EndGlobal
diff --git a/SocketStudyTest/SocketStudyTest.csproj b/SocketStudyTest/SocketStudyTest.csproj
new file mode 100644
index 0000000..b4c1743
--- /dev/null
+++ b/SocketStudyTest/SocketStudyTest.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
diff --git a/SocketStudyTest/SocketTest.cs b/SocketStudyTest/SocketTest.cs
new file mode 100644
index 0000000..36941e1
--- /dev/null
+++ b/SocketStudyTest/SocketTest.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SocketStudyTest
+{
+ public class SocketTest
+ {
+ [Fact]
+ public void Test()
+ {
+ var hostName = Dns.GetHostName();
+ var ipaddressList = Dns.GetHostAddresses(hostName,AddressFamily.InterNetwork);
+
+ var first = ipaddressList.FirstOrDefault(ip => ip.ToString().StartsWith("192"));
+ if (first !=null)
+ {
+
+ }
+
+ var dd = IPAddress.Any.ToString();
+ }
+ }
+}
diff --git a/SocketStudyTest/UseXunit.cs b/SocketStudyTest/UseXunit.cs
new file mode 100644
index 0000000..1fa7992
--- /dev/null
+++ b/SocketStudyTest/UseXunit.cs
@@ -0,0 +1,11 @@
+namespace SocketStudyTest
+{
+ public class UseXunit
+ {
+ [Fact]
+ public void Test1()
+ {
+ Assert.True(true,"ʹxunitԿܣ");
+ }
+ }
+}
\ No newline at end of file
diff --git a/SocketStudyTest/Usings.cs b/SocketStudyTest/Usings.cs
new file mode 100644
index 0000000..1df9fb7
--- /dev/null
+++ b/SocketStudyTest/Usings.cs
@@ -0,0 +1,8 @@
+global using Xunit;
+global using System.Net;
+global using System.Net.Sockets;
+global using System.IO;
+global using System.Net.Cache;
+global using System.Net.Mime;
+global using System.Net.NetworkInformation;
+global using System.Net.Security;
\ No newline at end of file