C#常规TcpListener
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的更多相关文章
- Taurus.MVC 微服务框架 入门开发教程:项目部署:1、微服务应用程序常规部署实现多开,节点扩容。
系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...
- CSS三个定位——常规、浮动、绝对定位
.dage { width: 868px; background: #5B8C75; border: 10px solid #A08C5A; margin-top: -125px; margin-le ...
- Windows Server 2008 R2常规安全设置及基本安全策略
这篇文章主要介绍了Windows Web Server 2008 R2服务器简单安全设置,需要的朋友可以参考下 用的腾讯云最早选购的时候悲催的只有Windows Server 2008 R2的系统,原 ...
- C# - 网络编程 之 TcpClient与TcpListener
TcpClient类 TcpListener类 TCP通信 UDP通信 参考:
- Oracle Recovery 01 - 常规恢复之完全恢复
背景:这里提到的常规恢复指的是数据库有完备可用的RMAN物理备份. 实验环境:RHEL6.4 + Oracle 11.2.0.4 DG primary. 一.常规恢复之完全恢复:不丢失数据 1.1 单 ...
- Oracle Recovery 02 - 常规恢复之不完全恢复
背景:这里提到的常规恢复指的是数据库有完备可用的RMAN物理备份. 实验环境:RHEL6.4 + Oracle 11.2.0.4 单实例. 二.常规恢复之不完全恢复:部分数据丢失 2.1 重做日志文件 ...
- git 常规使用小结
总结下 git 的常规使用: 一般我们使用 git 来维护项目代码. 前提背景: 远程服务器上代码库,包含分支: 1.master - 版本发布分支 2.dev - 平时开发用的分支 一般操作流程: ...
- 简单的c# TCP通讯(TcpListener)
简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TC ...
- Socket聊天室-TcpListener,TcpClient
参考自:http://blog.csdn.net/liguo9860/article/details/6148614 服务端:
随机推荐
- Shell脚本 硬盘监控
用shell 写了一个硬盘监控的小程序 #!/bin/bash MAX=95 EMAIL=zonghua@iyunshu.com PART=sda1 IP=`ifconfig |grep -w ...
- 《Java 8 in Action》Chapter 11:CompletableFuture:组合式异步编程
某个网站的数据来自Facebook.Twitter和Google,这就需要网站与互联网上的多个Web服务通信.可是,你并不希望因为等待某些服务的响应,阻塞应用程序的运行,浪费数十亿宝贵的CPU时钟周期 ...
- 实训第八天 有关python orm 的学习记录 常用方法02
继续沿用第七天数据库:def test2(request): # 1.xxx__lt 小于 :查询出年龄小于22的所有 ret=models.Person.objects.filter(age__lt ...
- 用pycharm自带的数据库创建项目00
一.生成表格1.创建模型类(在 models.py文件中创建一个person类并且继承models.Models类) 2.生成表格(在项目目录下)(1)生成迁移文件:在pycharm下方的命令行Ter ...
- 图解Java设计模式之UML类图
图解Java设计模式之UML类图 3.1 UML基本介绍 UML图 UML类图 3.1 UML基本介绍 1)UML – Unified modeling language UML(统一建模语言),是一 ...
- C#设计模式学习笔记:(15)迭代器模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7903617.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第三个模式--迭 ...
- ELK学习001:Elastic Stack简介
ELK简介: ELK Stack:ELK是Elasticsearch.Logstash.Kibana的缩写简称,这三者都是开源软件.ELK是5.0版本前的统称:这是一套统一的日志收集分析系统.它能够方 ...
- VSCode 完美整合前后端框架(angular2+.NET core)
首先打开命令行查看本地.NET版本. 通过命令行安装模板. dotnet new --install Microsoft.AspNetCore.SpaTemplates::* 创建demo目录,并用v ...
- 剑指offer-面试题59_1-滑动窗口的最大值-数组
/* 题目: 链接:https://www.nowcoder.com/questionTerminal/1624bc35a45c42c0bc17d17fa0cba788 来源:牛客网 给定一个数组和滑 ...
- linux命令——find
简介:find是Linux系统中的常用命令(应用程序)之一.它是用来在指定目录层次结构(指定目录的子目录以及子目录的子目录)中查找符合指定条件的文件和目录 一:语法结构 find [directory ...

