1.Xaml

 <Window x:Class="Server.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:Server"
mc:Ignorable="d"
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
WindowStartupLocation="CenterScreen" ResizeMode="NoResize"
Loaded="MainWindow_OnLoaded"
Title="Server" Height="450" Width="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TreeView x:Name="tvRemotes">
</TreeView>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Right" Margin="5,0,2,0" Padding="5" Text="本地地址"/>
<TextBox x:Name="tbIP" IsReadOnly="True" Grid.Row="0" Grid.Column="1" Margin="5" Text="127.0.0.1" />
<TextBlock HorizontalAlignment="Right" Margin="5,0,2,0" Padding="5" Grid.Row="1" Grid.Column="0" Text="本地端口:"/>
<TextBox x:Name="tbPort" Grid.Row="1" Grid.Column="1" Margin="5"/>
<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal">
<Button x:Name="btnListen" Content="开始监听" Margin="15" Click="BtnListen_OnClick"/>
<Button x:Name="btnDisconnect" Content="断开连接" IsEnabled="False" Margin="15" Click="BtnDisconnect_OnClick"/>
</StackPanel>
<ListView x:Name="lvDebugs" Grid.Row="3" Grid.ColumnSpan="2" Grid.Column="0" AlternationCount="2">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="ListView.AlternationIndex" Value="0">
<Setter Property="Background" Value="White"/>
</Trigger>
<Trigger Property="ListView.AlternationIndex" Value="1">
<Setter Property="Background" Value="WhiteSmoke"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Grid>
</Grid>
</Window>

2.CSharp

 using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading; namespace Server
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private TcpListener listener = null;
private List<Socket> socketList = new List<Socket>(); public class StateObject
{
public Socket workSocket = null;
public const int BUFFER_SIZE = ;
public byte[] buffer = new byte[BUFFER_SIZE];
} public MainWindow()
{
InitializeComponent();
} private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{ } /// <summary>
/// 开启监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnListen_OnClick(object sender, RoutedEventArgs e)
{
try
{
listener = new TcpListener(new IPEndPoint(IPAddress.Any, Convert.ToInt32(tbPort.Text)));
listener.Start();
listener.BeginAcceptSocket(new AsyncCallback(AcceptCallback), listener.Server); btnListen.IsEnabled = false;
btnDisconnect.IsEnabled = true;
}
catch (Exception ex)
{
Add2ListView("启动监听异常: " + ex.Message);
}
} private void AcceptCallback(IAsyncResult ar)
{
Socket server = (Socket) ar.AsyncState;
try
{
Socket socket = server.EndAccept(ar);
string strAddr = socket.RemoteEndPoint.ToString();
socketList.Add(socket);
Dispatcher.Invoke(() =>
{
Add2TreeView(strAddr);
Add2ListView(strAddr);
}, DispatcherPriority.Normal);
var bytes = Encoding.UTF8.GetBytes("welcome.");
socket.Send(bytes);
StateObject so = new StateObject();
so.workSocket = socket;
socket.BeginReceive(so.buffer, , StateObject.BUFFER_SIZE, SocketFlags.None,
new AsyncCallback(ReceiveCallback), so); server.BeginAccept(new AsyncCallback(AcceptCallback), server);
}
catch (Exception)
{
// ignored
}
} /// <summary>
/// 断开监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void BtnDisconnect_OnClick(object sender, RoutedEventArgs e)
{
try
{
foreach (var socket in socketList)
{
if (socket != null && socket.Connected)
{
socket.Shutdown(SocketShutdown.Both); await Task.Delay();
socket.Close();
}
}
socketList.Clear(); listener.Stop();
// 清空客户端列表
tvRemotes.Items.Clear(); btnListen.IsEnabled = true;
btnDisconnect.IsEnabled = false;
}
catch (Exception ex)
{
Add2ListView("断开监听异常: " + ex.Message);
}
} private void ReceiveCallback(IAsyncResult ar)
{
StateObject so = ar.AsyncState as StateObject;
Socket socket = so.workSocket;
if (socket != null && socket.Connected)
{
int read = socket.EndReceive(ar);
ar.AsyncWaitHandle.Close();
if (read > )
{
Dispatcher.Invoke(() => Add2ListView(text: socket.RemoteEndPoint + ": " + Encoding.UTF8.GetString(so.buffer)),
DispatcherPriority.Normal);
socket.BeginReceive(so.buffer, , StateObject.BUFFER_SIZE, SocketFlags.None,
new AsyncCallback(ReceiveCallback), so);
}
else
{
Dispatcher.Invoke(() =>
{
Add2ListView(socket.RemoteEndPoint + ": 客户端连接已断开.");
for (int i = ; i < tvRemotes.Items.Count; i++)
{
TreeViewItem tvi = (TreeViewItem)tvRemotes.Items[i];
if ((string)tvi.Tag == socket.RemoteEndPoint.ToString())
{
tvRemotes.Items.Remove(tvi);
socketList.Remove(socket);
return;
}
}
},
DispatcherPriority.Normal); socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
} private void Add2TreeView(string strRemote)
{
TreeViewItem tvi = new TreeViewItem();
tvi.Tag = strRemote;
StackPanel sp = new StackPanel();
sp.Orientation = Orientation.Horizontal;
sp.Children.Add(new PackIcon { Kind = PackIconKind.Devices });
sp.Children.Add(new TextBlock { Text = $"{strRemote}" });
tvi.Items.Add(sp);
tvRemotes.Items.Add(tvi);
} private void Add2ListView(string text)
{
TextBlock tb = new TextBlock { Text = text };
lvDebugs.Items.Add(tb);
}
}
}

3.运行效果

C#常规TcpListener的更多相关文章

  1. Taurus.MVC 微服务框架 入门开发教程:项目部署:1、微服务应用程序常规部署实现多开,节点扩容。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

  2. CSS三个定位——常规、浮动、绝对定位

    .dage { width: 868px; background: #5B8C75; border: 10px solid #A08C5A; margin-top: -125px; margin-le ...

  3. Windows Server 2008 R2常规安全设置及基本安全策略

    这篇文章主要介绍了Windows Web Server 2008 R2服务器简单安全设置,需要的朋友可以参考下 用的腾讯云最早选购的时候悲催的只有Windows Server 2008 R2的系统,原 ...

  4. C# - 网络编程 之 TcpClient与TcpListener

    TcpClient类 TcpListener类 TCP通信 UDP通信 参考:

  5. Oracle Recovery 01 - 常规恢复之完全恢复

    背景:这里提到的常规恢复指的是数据库有完备可用的RMAN物理备份. 实验环境:RHEL6.4 + Oracle 11.2.0.4 DG primary. 一.常规恢复之完全恢复:不丢失数据 1.1 单 ...

  6. Oracle Recovery 02 - 常规恢复之不完全恢复

    背景:这里提到的常规恢复指的是数据库有完备可用的RMAN物理备份. 实验环境:RHEL6.4 + Oracle 11.2.0.4 单实例. 二.常规恢复之不完全恢复:部分数据丢失 2.1 重做日志文件 ...

  7. git 常规使用小结

    总结下 git 的常规使用: 一般我们使用 git 来维护项目代码. 前提背景: 远程服务器上代码库,包含分支: 1.master - 版本发布分支 2.dev - 平时开发用的分支 一般操作流程: ...

  8. 简单的c# TCP通讯(TcpListener)

      简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TC ...

  9. Socket聊天室-TcpListener,TcpClient

    参考自:http://blog.csdn.net/liguo9860/article/details/6148614 服务端:

随机推荐

  1. 大文件切割(split)

    split提供两种方式对文件进行切割: 根据行数切割,通过-l参数指定需要切割的行数 根据大小切割,通过-b参数指定需要切割的大小 1.1 根据行数切割 如下以一个3.4G大小的日志文件做切割演示,每 ...

  2. Kvm 简介 安装 使用 桥接网络

    KVM 全称是 基于内核的虚拟机(Kernel-based Virtual Machine),它是一个 Linux 的一个内核模块,该内核模块使得 Linux 变成了一个 Hypervisor: 它由 ...

  3. Django设置异步任务

    1.安装Django-celery 包:pip install django-celery==3.2.2 2.开启redis服务 需要使用redis做broker,所以在使用异步和定时任务时需要开启r ...

  4. Error serializing object:序列化对象时出错

    序列化对象时出错 :Error serializing object. Error serializing object. Cause: java.io.NotSerializableExceptio ...

  5. C#设计模式学习笔记:(18)状态模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8032683.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第六个模式--状 ...

  6. 关于mac下redis的安装和部署

    近来学习scrap分布式,需要用到redis,但以前没接触过,所以记录一下自己的安装过程. 准备:Mac,redis-5.0.4.tar.gz 1.压缩包到官网下(建议下载稳定版)网址:redis.i ...

  7. Spark基础和RDD

    spark 1. Spark的四大特性 速度快 spark比mapreduce快的两个原因 基于内存 1. mapreduce任务后期在计算的是时候,每一个job的输出结果都会落地到磁盘,后续有其他的 ...

  8. SDI011 读卡器自动发送00A4选择指令 解决方法

    如标题,SDI读卡器会自动发送 004A的应用选择指令 解决方法: 是Certificate Propagation 服务 弄的, 关闭就好了

  9. 持续更新phpstorm h和pycharm 激活码

    1.hosts文件写入 0.0.0.0 account.jetbrains.com0.0.0.0 www.jetbrains.com 2.激活码: AHD9079DKZ-eyJsaWNlbnNlSWQ ...

  10. C#画图之饼图

    public JsonResult DrawPie() { // 预置颜色 List<Color> colors = new List<Color>() { Color.Fro ...