添加项目

master
bicijinlian
parent 8eb8f56118
commit e92a101498

@ -0,0 +1,9 @@
<Application x:Class="SocketStudy.ClientApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SocketStudy.ClientApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

@ -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
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

@ -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)
)]

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

@ -0,0 +1,34 @@
<Window x:Class="SocketStudy.ClientApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SocketStudy.ClientApp"
mc:Ignorable="d"
Title=" 客户端" Height="677" Width="800" Icon="/Images/logo.ico" ResizeMode="CanMinimize">
<Grid Margin="0,0,0,74">
<TextBox x:Name="textBox_ServerAddress" HorizontalAlignment="Left" Margin="180,24,0,0" TextWrapping="Wrap" Text="192.168.1.66" VerticalAlignment="Top" Width="190" FontSize="18" Height="45" VerticalContentAlignment="Center" Padding="5,5,5,5" FontWeight="Bold" HorizontalContentAlignment="Center"/>
<Label x:Name="lable_address_title" Content="远程服务器地址:" HorizontalAlignment="Left" Margin="25,24,0,0" VerticalAlignment="Top" Height="45" FontSize="18" VerticalContentAlignment="Center" Width="150" BorderThickness="2,2,2,2" Grid.ColumnSpan="2"/>
<Label x:Name="lable_server_port_title" Content="远程服务端口号:" HorizontalAlignment="Left" Margin="517,24,0,0" VerticalAlignment="Top" Height="45" FontSize="18" VerticalContentAlignment="Center" Width="150" BorderThickness="2,2,2,2"/>
<TextBox x:Name="textBox_ServerPort" HorizontalAlignment="Left" Margin="675,24,0,0" TextWrapping="Wrap" Text="6601" VerticalAlignment="Top" Width="87" FontSize="18" Height="45" VerticalContentAlignment="Center" Padding="5,5,5,5" FontWeight="Bold" HorizontalContentAlignment="Center"/>
<RichTextBox x:Name="richTextBox_Log" Margin="25,342,35,-51" FontSize="14" VerticalScrollBarVisibility="Auto">
<FlowDocument>
<Paragraph>
<Run Text=""/>
</Paragraph>
</FlowDocument>
</RichTextBox>
<Label x:Name="lable_SendData_Title" Content="发送数据:" HorizontalAlignment="Left" Margin="25,260,0,0" VerticalAlignment="Top" Height="45" FontSize="18" VerticalContentAlignment="Center" Width="101" BorderThickness="2,2,2,2"/>
<TextBox x:Name="textBox_SendData" HorizontalAlignment="Left" Margin="25,260,0,0" TextWrapping="Wrap" Text="你好,我是来自客户端的数据!" VerticalAlignment="Top" Width="562" FontSize="18" Height="45" VerticalContentAlignment="Center" Padding="5,5,5,5" FontWeight="Bold" HorizontalContentAlignment="Left"/>
<Button x:Name="btn_Connect" Content="连接服务器" HorizontalAlignment="Left" Margin="25,169,0,0" VerticalAlignment="Top" Height="45" Width="122" FontSize="18" Click="btn_Connect_Click"/>
<Button x:Name="btn_Close" Content="关闭连接" HorizontalAlignment="Left" Margin="248,169,0,0" VerticalAlignment="Top" Height="45" Width="122" FontSize="18" RenderTransformOrigin="1.482,0.633" Click="btn_Close_Click"/>
<Button x:Name="btn_Send" Content="发送数据" HorizontalAlignment="Left" Margin="640,261,0,0" VerticalAlignment="Top" Height="45" Width="122" FontSize="18" RenderTransformOrigin="1.482,0.633" Click="btn_Send_Click"/>
<Label x:Name="lable_client_port_title" Content="本地连接端口号:" HorizontalAlignment="Left" Margin="517,95,0,0" VerticalAlignment="Top" Height="45" FontSize="18" VerticalContentAlignment="Center" Width="150" BorderThickness="2,2,2,2"/>
<TextBox x:Name="textBox_ClientPort" HorizontalAlignment="Left" Margin="674,95,0,0" TextWrapping="Wrap" Text="6901" VerticalAlignment="Top" Width="88" FontSize="18" Height="45" VerticalContentAlignment="Center" Padding="5,5,5,5" FontWeight="Bold" HorizontalContentAlignment="Center"/>
<Button x:Name="btn_Dispose" Content="释放连接" HorizontalAlignment="Left" Margin="465,169,0,0" VerticalAlignment="Top" Height="45" Width="122" FontSize="18" RenderTransformOrigin="1.482,0.633" Click="btn_Dispose_Click"/>
<TextBox x:Name="textBox_ClientAddress" HorizontalAlignment="Left" Margin="180,95,0,0" TextWrapping="Wrap" Text="192.168.1.66" VerticalAlignment="Top" Width="190" FontSize="18" Height="45" VerticalContentAlignment="Center" Padding="5,5,5,5" FontWeight="Bold" HorizontalContentAlignment="Center"/>
<Label x:Name="lable_client_address_title" Content="本地连接地址:" HorizontalAlignment="Left" Margin="25,95,0,0" VerticalAlignment="Top" Height="45" FontSize="18" VerticalContentAlignment="Center" Width="150" BorderThickness="2,2,2,2" RenderTransformOrigin="-0.139,0.451"/>
<Button x:Name="btn_Back" Content="备用按钮" HorizontalAlignment="Left" Margin="640,169,0,0" VerticalAlignment="Top" Height="45" Width="122" FontSize="18" RenderTransformOrigin="1.482,0.633" />
</Grid>
</Window>

@ -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
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private TcpClient _tcpClient;
public MainWindow()
{
InitializeComponent();
}
/// <summary>
/// 连接服务网络
/// </summary>
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
{
}
}
/// <summary>
/// 关闭网络连接
/// </summary>
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($"连接已成功关闭!");
}
/// <summary>
/// 使用连接,发送数据给服务器
/// </summary>
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
{
}
}
/// <summary>
/// 释放连接
/// </summary>
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("连接已成功释放!");
}
/// <summary>
/// 写日志信息
/// </summary>
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);
}));
}
}
}

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<None Remove="Images\logo.ico" />
<None Remove="Images\logo.red.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Images\logo.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
<Resource Include="Images\logo.red.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
</ItemGroup>
</Project>

@ -0,0 +1,9 @@
<Application x:Class="SocketStudy.ServerApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SocketStudy.ServerApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

@ -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
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

@ -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)
)]

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

@ -0,0 +1,29 @@
<Window x:Class="SocketStudy.ServerApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SocketStudy.ServerApp"
mc:Ignorable="d"
Title=" 服务器" Height="593" Width="800" Icon="/Images/logo.ico" ContentRendered="Window_ContentRendered">
<Grid>
<Label x:Name="lable_address_title" Content="服务地址:" HorizontalAlignment="Left" Margin="20,24,0,0" VerticalAlignment="Top" Height="45" FontSize="18" VerticalContentAlignment="Center" Width="101" BorderThickness="2,2,2,2"/>
<Label x:Name="lable_port_title" Content="端口号:" HorizontalAlignment="Left" Margin="311,24,0,0" VerticalAlignment="Top" Height="45" FontSize="18" VerticalContentAlignment="Center" Width="79" BorderThickness="2,2,2,2"/>
<TextBox x:Name="textBox_ServerPort" HorizontalAlignment="Left" Margin="390,25,0,0" TextWrapping="Wrap" Text="6601" VerticalAlignment="Top" Width="86" FontSize="18" Height="45" VerticalContentAlignment="Center" Padding="5,5,5,5" FontWeight="Bold" HorizontalContentAlignment="Center"/>
<RichTextBox x:Name="richTextBox_Log" Margin="30,170,30,23" FontSize="14" Grid.ColumnSpan="2" VerticalScrollBarVisibility="Auto">
<FlowDocument>
<Paragraph>
<Run Text=""/>
</Paragraph>
</FlowDocument>
</RichTextBox>
<Label x:Name="lable_SendData_Title" Content="发送数据:" HorizontalAlignment="Left" Margin="20,97,0,0" VerticalAlignment="Top" Height="45" FontSize="18" VerticalContentAlignment="Center" Width="101" BorderThickness="2,2,2,2"/>
<TextBox x:Name="textBox_SendData" HorizontalAlignment="Left" Margin="121,97,0,0" TextWrapping="Wrap" Text="你好,我是远程服务器数据!" VerticalAlignment="Top" Width="253" FontSize="18" Height="45" VerticalContentAlignment="Center" Padding="5,5,5,5" FontWeight="Bold" HorizontalContentAlignment="Left"/>
<Button x:Name="btn_Start" Content="启动服务" HorizontalAlignment="Left" Margin="499,25,0,0" VerticalAlignment="Top" Height="45" Width="122" FontSize="18" Click="btn_Start_Click"/>
<Button x:Name="btn_Stop" Content="停止服务" HorizontalAlignment="Left" Margin="643,24,0,0" VerticalAlignment="Top" Height="45" Width="122" FontSize="18" RenderTransformOrigin="1.482,0.633" Click="btn_Stop_Click"/>
<Button x:Name="btn_Send" Content="发送数据" HorizontalAlignment="Left" Margin="643,97,0,0" VerticalAlignment="Top" Height="45" Width="122" FontSize="18" RenderTransformOrigin="1.482,0.633" Click="btn_Send_Click"/>
<ComboBox x:Name="comboBox_Clients" HorizontalAlignment="Left" Margin="390,97,0,0" VerticalAlignment="Top" Width="231" Height="45" FontSize="18" HorizontalContentAlignment="Left" VerticalContentAlignment="Center"/>
<ComboBox x:Name="comboBox_ServerAddress" HorizontalAlignment="Left" Margin="121,25,0,0" VerticalAlignment="Top" Width="185" Height="45" FontSize="18" HorizontalContentAlignment="Left" VerticalContentAlignment="Center"/>
</Grid>
</Window>

@ -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
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//服务监听
private TcpListener _tcpServer = null;
//存放活动客户端连接字典
private ConcurrentDictionary<string, TcpClient> _remoteClientDic = new ConcurrentDictionary<string, TcpClient>();
//监听线程
private Thread _listenerThread;
public MainWindow()
{
InitializeComponent();
}
/// <summary>
/// 窗口呈现完毕事件
/// </summary>
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);
}
}
/// <summary>
/// 启动服务
/// </summary>
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("服务启动完毕!");
}
/// <summary>
/// 停止服务
/// </summary>
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("服务停止完成!");
}
/// <summary>
/// 发送数据
/// </summary>
private void btn_Send_Click(object sender, RoutedEventArgs e)
{
if (_remoteClientDic.Count == 0 || comboBox_Clients.Items.Count ==0)
{
WriteLog("没有正在连接的客户端,请先使用客户端连接到本服务器!");
return;
}
var clientForSend=new List<TcpClient>();
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
{
}
}
}
/// <summary>
/// 写日志信息
/// </summary>
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);
}));
}
/// <summary>
/// 重新设置客户端列表项
/// </summary>
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]);
}
}
}));
}
/// <summary>
/// 监听客户端连接方法
/// </summary>
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}");
}
/// <summary>
/// 接收客户端数据方法
/// </summary>
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}");
}
}
}
}

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<None Remove="Images\logo.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Images\logo.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
</ItemGroup>
</Project>

@ -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

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>

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

@ -0,0 +1,11 @@
namespace SocketStudyTest
{
public class UseXunit
{
[Fact]
public void Test1()
{
Assert.True(true,"使用xunit测试框架");
}
}
}

@ -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;
Loading…
Cancel
Save