Socket 套接字

Socket

xaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<StackPanel Margin="10">
<TextBlock Text="IP" />
<TextBox x:Name="textBoxIP" Text="127.0.0.1" />
<TextBlock Text="端口" />
<TextBox x:Name="textBoxPort" Text="8081" />
<UniformGrid Margin="0,10" Columns="2">
<Button
x:Name="buttonConnect"
Click="buttonConnect_Click"
Content="连 接" />
<Button
x:Name="buttonClose"
Click="buttonClose_Click"
Content="关 闭"
IsEnabled="False" />
</UniformGrid>
<Button
x:Name="buttonSend"
Click="buttonSend_Click"
Content="发 送"
IsEnabled="False" />
</StackPanel>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox x:Name="textBoxConsole" IsReadOnly="True" />
<TextBox x:Name="textBoxInput" Grid.Row="1" />
</Grid>
</Grid>

cs

server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows;

namespace TestSocketServer
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private Socket _serverSocket;
private List<Socket> _acceptSockets = new List<Socket>();
public MainWindow()
{
InitializeComponent();
}

private void buttonConnect_Click(object sender, RoutedEventArgs e)
{
//创建用于监听连接的套接字
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse(textBoxIP.Text);
int port = int.Parse(textBoxPort.Text);
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
//绑定端口
_serverSocket.Bind(ipEndPoint);
_serverSocket.Listen(10);
ChangButtonState(true);
Task.Factory.StartNew(() =>
{
//开始监听客户端连接
while (true)
{
try
{
//接收客户端连接
Socket acceptSocket = _serverSocket.Accept();
//记录客户端连接套接字
_acceptSockets.Add(acceptSocket);
WriteConsole($"客户端连接成功");
Task.Factory.StartNew(() =>
{
//开始监听客户端消息
while (acceptSocket.Connected)
{
try
{
byte[] recieve = new byte[1024];
acceptSocket.Receive(recieve);
if (recieve.Length > 0)
{
//打印接收数据
WriteConsole($"接收 - {Encoding.UTF8.GetString(recieve)}");
}
}
catch (Exception ex)
{
WriteConsole(ex.Message);
}
}
});
}
catch (Exception ex)
{
WriteConsole(ex.Message);
break;
}
}
});
}

private void buttonClose_Click(object sender, RoutedEventArgs e)
{
_serverSocket.Close();
_acceptSockets.ForEach(acceptSocket => { acceptSocket.Close(); });
_acceptSockets.Clear();
MessageBox.Show("服务器已关闭");
WriteConsole("服务器已关闭");
ChangButtonState(false);
}

private void buttonSend_Click(object sender, RoutedEventArgs e)
{

byte[] send = Encoding.UTF8.GetBytes(textBoxInput.Text);
List<Socket> rmsk = new List<Socket>();
_acceptSockets.ForEach(socket =>
{
if (socket.Connected)
{
//调用Send()向客户端发送数据
socket.Send(send);
}
else
{
rmsk.Add(socket);
}
});
rmsk.ForEach(socket =>
{
_acceptSockets.Remove(socket);
});
WriteConsole($"发送 - {textBoxInput.Text}");
textBoxInput.Clear();
}

private void ChangButtonState(bool connected)
{
this.Dispatcher.Invoke(() =>
{
buttonClose.IsEnabled = connected;
buttonSend.IsEnabled = connected;
buttonConnect.IsEnabled = !connected;
});
}

private void WriteConsole(string msg)
{
this.Dispatcher.Invoke(() =>
{
textBoxConsole.Text += $"{DateTime.Now:yy-MM-dd hh:mm:ss} {msg}\r\n";
});
}
}
}

client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows;

namespace TestSocketClient
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private Socket _clientSocket;

private void buttonConnect_Click(object sender, RoutedEventArgs e)
{
//声明负责通信的套接字
_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
WriteConsole("正在连接...");
IPAddress IP = IPAddress.Parse(textBoxIP.Text);
int Port = int.Parse(textBoxPort.Text);
IPEndPoint iPEndPoint = new IPEndPoint(IP, Port);
try
{
//用socket对象的Connect()方法以上面建立的IPEndPoint对象做为参数,向服务器发出连接请求
_clientSocket.Connect(iPEndPoint);
WriteConsole($"{textBoxIP.Text}连接成功");
ChangButtonState(true);
Task.Factory.StartNew(() =>
{
while (_clientSocket.Connected)
{
try
{
//调用Receive()接收字节数据
byte[] receive = new byte[1024];
_clientSocket.Receive(receive);
if (receive.Length > 0)
{
WriteConsole($"接收 - {Encoding.UTF8.GetString(receive)}");
}
}
catch (Exception ex)
{
WriteConsole(ex.Message);
}
}
ChangButtonState(false);
});
}
catch
{
MessageBox.Show("服务器未打开");
}
}

private void buttonClose_Click(object sender, RoutedEventArgs e)
{
//关闭套接字
_clientSocket.Close();
MessageBox.Show("已关闭连接");
WriteConsole("客户端已关闭");
}

private void buttonSend_Click(object sender, RoutedEventArgs e)
{
byte[] send = Encoding.UTF8.GetBytes(textBoxInput.Text);
//调用Send()函数发送数据
_clientSocket.Send(send);
WriteConsole($"发送 - {textBoxInput.Text}");
textBoxInput.Clear();
}

private void ChangButtonState(bool connected)
{
this.Dispatcher.Invoke(() =>
{
buttonClose.IsEnabled = connected;
buttonSend.IsEnabled = connected;
buttonConnect.IsEnabled = !connected;
});
}

private void WriteConsole(string msg)
{
this.Dispatcher.Invoke(() =>
{
textBoxConsole.Text += $"{DateTime.Now:yy-MM-dd hh:mm:ss} {msg}\r\n";
});
}
}
}

源码仓库

WineMonk/SocketStudy: SocketStudy (github.com)