C#常规TcpListener

1.Xaml

 1 <Window x:Class="Server.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:Server"
 7         mc:Ignorable="d"
 8         xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
 9         WindowStartupLocation="CenterScreen" ResizeMode="NoResize"
10         Loaded="MainWindow_OnLoaded"
11         Title="Server" Height="450" Width="600">
12     <Grid>
13         <Grid.ColumnDefinitions>
14             <ColumnDefinition Width="Auto"/>
15             <ColumnDefinition Width="1*"/>
16         </Grid.ColumnDefinitions>
17         <TreeView x:Name="tvRemotes">
18         </TreeView>
19         <Grid Grid.Column="1">
20             <Grid.RowDefinitions>
21                 <RowDefinition Height="Auto"/>
22                 <RowDefinition Height="Auto"/>
23                 <RowDefinition Height="Auto"/>
24                 <RowDefinition Height="1*"/>
25             </Grid.RowDefinitions>
26             <Grid.ColumnDefinitions>
27                 <ColumnDefinition />
28                 <ColumnDefinition Width="Auto"/>
29             </Grid.ColumnDefinitions>
30             <TextBlock HorizontalAlignment="Right" Margin="5,0,2,0" Padding="5" Text="本地地址"/>
31             <TextBox x:Name="tbIP" IsReadOnly="True" Grid.Row="0" Grid.Column="1" Margin="5" Text="127.0.0.1" />
32             <TextBlock HorizontalAlignment="Right" Margin="5,0,2,0" Padding="5" Grid.Row="1" Grid.Column="0" Text="本地端口:"/>
33             <TextBox x:Name="tbPort" Grid.Row="1" Grid.Column="1" Margin="5"/>
34             <StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal">
35                 <Button x:Name="btnListen" Content="开始监听" Margin="15" Click="BtnListen_OnClick"/>
36                 <Button x:Name="btnDisconnect" Content="断开连接" IsEnabled="False" Margin="15" Click="BtnDisconnect_OnClick"/>
37             </StackPanel>
38             <ListView x:Name="lvDebugs" Grid.Row="3" Grid.ColumnSpan="2" Grid.Column="0" AlternationCount="2">
39                 <ListView.ItemContainerStyle>
40                     <Style TargetType="ListViewItem">
41                         <Style.Triggers>
42                             <Trigger Property="ListView.AlternationIndex" Value="0">
43                                 <Setter Property="Background" Value="White"/>
44                             </Trigger>
45                             <Trigger Property="ListView.AlternationIndex" Value="1">
46                                 <Setter Property="Background" Value="WhiteSmoke"/>
47                             </Trigger>
48                         </Style.Triggers>
49                     </Style>
50                 </ListView.ItemContainerStyle>
51             </ListView>
52         </Grid>
53     </Grid>
54 </Window>
View Code

2.CSharp

  1 using MaterialDesignThemes.Wpf;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Net;
  5 using System.Net.Sockets;
  6 using System.Text;
  7 using System.Threading.Tasks;
  8 using System.Windows;
  9 using System.Windows.Controls;
 10 using System.Windows.Threading;
 11 
 12 namespace Server
 13 {
 14     /// <summary>
 15     /// MainWindow.xaml 的交互逻辑
 16     /// </summary>
 17     public partial class MainWindow : Window
 18     {
 19         private TcpListener listener = null;
 20         private List<Socket> socketList = new List<Socket>();
 21 
 22         public class StateObject
 23         {
 24             public Socket workSocket = null;
 25             public const int BUFFER_SIZE = 1024;
 26             public byte[] buffer = new byte[BUFFER_SIZE];
 27         }
 28 
 29         public MainWindow()
 30         {
 31             InitializeComponent();
 32         }
 33 
 34         private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
 35         {
 36 
 37         }
 38 
 39         /// <summary>
 40         /// 开启监听
 41         /// </summary>
 42         /// <param name="sender"></param>
 43         /// <param name="e"></param>
 44         private void BtnListen_OnClick(object sender, RoutedEventArgs e)
 45         {
 46             try
 47             {
 48                 listener = new TcpListener(new IPEndPoint(IPAddress.Any, Convert.ToInt32(tbPort.Text)));
 49                 listener.Start();
 50                 listener.BeginAcceptSocket(new AsyncCallback(AcceptCallback), listener.Server);
 51 
 52                 btnListen.IsEnabled = false;
 53                 btnDisconnect.IsEnabled = true;
 54             }
 55             catch (Exception ex)
 56             {
 57                 Add2ListView("启动监听异常: " + ex.Message);
 58             }
 59         }
 60 
 61         private void AcceptCallback(IAsyncResult ar)
 62         {
 63             Socket server = (Socket) ar.AsyncState;
 64             try
 65             {
 66                 Socket socket = server.EndAccept(ar);
 67                 string strAddr = socket.RemoteEndPoint.ToString();
 68                 socketList.Add(socket);
 69                 Dispatcher.Invoke(() =>
 70                 {
 71                     Add2TreeView(strAddr);
 72                     Add2ListView(strAddr);
 73                 }, DispatcherPriority.Normal);
 74                 var bytes = Encoding.UTF8.GetBytes("welcome.");
 75                 socket.Send(bytes);
 76                 StateObject so = new StateObject();
 77                 so.workSocket = socket;
 78                 socket.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None,
 79                     new AsyncCallback(ReceiveCallback), so);
 80 
 81                 server.BeginAccept(new AsyncCallback(AcceptCallback), server);
 82             }
 83             catch (Exception)
 84             {
 85                 // ignored
 86             }
 87         }
 88 
 89         /// <summary>
 90         /// 断开监听
 91         /// </summary>
 92         /// <param name="sender"></param>
 93         /// <param name="e"></param>
 94         private async void BtnDisconnect_OnClick(object sender, RoutedEventArgs e)
 95         {
 96             try
 97             {
 98                 foreach (var socket in socketList)
 99                 {
100                     if (socket != null && socket.Connected) 
101                     {
102                         socket.Shutdown(SocketShutdown.Both);
103 
104                         await Task.Delay(10);
105                         socket.Close();
106                     }
107                 }
108                 socketList.Clear();
109 
110                 listener.Stop();
111                 // 清空客户端列表
112                 tvRemotes.Items.Clear();
113 
114                 btnListen.IsEnabled = true;
115                 btnDisconnect.IsEnabled = false;
116             }
117             catch (Exception ex)
118             {
119                 Add2ListView("断开监听异常: " + ex.Message);
120             }
121         }
122 
123         private void ReceiveCallback(IAsyncResult ar)
124         {
125             StateObject so = ar.AsyncState as StateObject;
126             Socket socket = so.workSocket;
127             if (socket != null && socket.Connected)
128             {
129                 int read = socket.EndReceive(ar);
130                 ar.AsyncWaitHandle.Close();
131                 if (read > 0)
132                 {
133                     Dispatcher.Invoke(() => Add2ListView(text: socket.RemoteEndPoint + ": " + Encoding.UTF8.GetString(so.buffer)),
134                         DispatcherPriority.Normal);
135                     socket.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None,
136                         new AsyncCallback(ReceiveCallback), so);
137                 }
138                 else
139                 {
140                     Dispatcher.Invoke(() =>
141                         {
142                             Add2ListView(socket.RemoteEndPoint + ": 客户端连接已断开.");
143                             for (int i = 0; i < tvRemotes.Items.Count; i++)
144                             {
145                                 TreeViewItem tvi = (TreeViewItem)tvRemotes.Items[i];
146                                 if ((string)tvi.Tag == socket.RemoteEndPoint.ToString())
147                                 {
148                                     tvRemotes.Items.Remove(tvi);
149                                     socketList.Remove(socket);
150                                     return;
151                                 }
152                             }
153                         },
154                         DispatcherPriority.Normal);
155 
156                     socket.Shutdown(SocketShutdown.Both);
157                     socket.Close();
158                 }
159             }
160         }
161 
162         private void Add2TreeView(string strRemote)
163         {
164             TreeViewItem tvi = new TreeViewItem();
165             tvi.Tag = strRemote;
166             StackPanel sp = new StackPanel();
167             sp.Orientation = Orientation.Horizontal;
168             sp.Children.Add(new PackIcon { Kind = PackIconKind.Devices });
169             sp.Children.Add(new TextBlock { Text = $"{strRemote}" });
170             tvi.Items.Add(sp);
171             tvRemotes.Items.Add(tvi);
172         }
173 
174         private void Add2ListView(string text)
175         {
176             TextBlock tb = new TextBlock { Text = text };
177             lvDebugs.Items.Add(tb);
178         }
179     }
180 }
View Code

3.运行效果

posted @ 2019-09-30 01:12  非法关键字  阅读(641)  评论(0编辑  收藏  举报