客户端代码:
界面代码:
namespace ClientWinform
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SendToBtn = new System.Windows.Forms.Button();
this.IPText = new System.Windows.Forms.TextBox();
this.PortText = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.SendMsg = new System.Windows.Forms.TextBox();
this.TextMsg = new System.Windows.Forms.RichTextBox();
this.ConnectBtn = new System.Windows.Forms.Button();
this.DisconnectBtn = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// SendToBtn
//
this.SendToBtn.Location = new System.Drawing.Point(713, 415);
this.SendToBtn.Name = "SendToBtn";
this.SendToBtn.Size = new System.Drawing.Size(75, 23);
this.SendToBtn.TabIndex = 0;
this.SendToBtn.Text = "发送";
this.SendToBtn.UseVisualStyleBackColor = true;
this.SendToBtn.Click += new System.EventHandler(this.SendToBtn_Click);
//
// IPText
//
this.IPText.Location = new System.Drawing.Point(35, 6);
this.IPText.Name = "IPText";
this.IPText.Size = new System.Drawing.Size(209, 23);
this.IPText.TabIndex = 0;
this.IPText.KeyDown += new System.Windows.Forms.KeyEventHandler(this.IPText_OnKeyDown);
//
// PortText
//
this.PortText.Location = new System.Drawing.Point(295, 6);
this.PortText.Name = "PortText";
this.PortText.Size = new System.Drawing.Size(124, 23);
this.PortText.TabIndex = 3;
this.PortText.KeyDown += new System.Windows.Forms.KeyEventHandler(this.PortText_OnKeyDown);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(10, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(19, 17);
this.label1.TabIndex = 0;
this.label1.Text = "IP";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(257, 10);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(32, 17);
this.label2.TabIndex = 2;
this.label2.Text = "端口";
//
// SendMsg
//
this.SendMsg.Location = new System.Drawing.Point(10, 415);
this.SendMsg.Name = "SendMsg";
this.SendMsg.Size = new System.Drawing.Size(697, 23);
this.SendMsg.TabIndex = 4;
this.SendMsg.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown_MsgSend);
//
// TextMsg
//
this.TextMsg.Location = new System.Drawing.Point(10, 35);
this.TextMsg.Name = "TextMsg";
this.TextMsg.Size = new System.Drawing.Size(778, 374);
this.TextMsg.TabIndex = 5;
this.TextMsg.Text = "";
this.TextMsg.TextChanged += new System.EventHandler(this.TextMsg_TextChanged);
//
// ConnectBtn
//
this.ConnectBtn.Location = new System.Drawing.Point(445, 6);
this.ConnectBtn.Name = "ConnectBtn";
this.ConnectBtn.Size = new System.Drawing.Size(83, 23);
this.ConnectBtn.TabIndex = 6;
this.ConnectBtn.Text = "连接服务器";
this.ConnectBtn.UseVisualStyleBackColor = true;
this.ConnectBtn.Click += new System.EventHandler(this.ConnectBtn_Click);
//
// DisconnectBtn
//
this.DisconnectBtn.Location = new System.Drawing.Point(545, 6);
this.DisconnectBtn.Name = "DisconnectBtn";
this.DisconnectBtn.Size = new System.Drawing.Size(79, 23);
this.DisconnectBtn.TabIndex = 7;
this.DisconnectBtn.Text = "断开服务器";
this.DisconnectBtn.UseVisualStyleBackColor = true;
this.DisconnectBtn.Click += new System.EventHandler(this.DisconnectBtn_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.DisconnectBtn);
this.Controls.Add(this.ConnectBtn);
this.Controls.Add(this.TextMsg);
this.Controls.Add(this.SendMsg);
this.Controls.Add(this.IPText);
this.Controls.Add(this.PortText);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.SendToBtn);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Button SendToBtn;
private TextBox IPText;
private Label label1;
private Label label2;
private TextBox PortText;
private TextBox SendMsg;
private RichTextBox TextMsg;
private Button ConnectBtn;
private Button DisconnectBtn;
}
}
客户端执行代码:
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ClientWinform
{
public partial class Form1 : Form
{
private IPAddress remoteIPAddress;
private int remotePort;
private Socket socket;
private byte[] dataReceive = new byte[1024];
private Thread th1;
public Form1()
{
InitializeComponent();
}
private void Init()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//定义本地接收数据的端口
IPEndPoint localHost = new IPEndPoint(IPAddress.Any, 30080);
socket.Bind(localHost);
}
private void OnChangeTextMsg(string msg)
{
this.TextMsg.AppendText(msg);
}
private void IPText_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab)
{
if (!IPAddress.TryParse(IPText.Text, out remoteIPAddress))
{
MessageBox.Show("请输入正确的IP地址");
IPText.Text = "";
}
else
{
TextMsg.AppendText($"IP:{remoteIPAddress}\r\n");
}
}
}
private void PortText_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab)
{
if (!int.TryParse(PortText.Text, out remotePort))
{
MessageBox.Show("请输入正确的端口");
PortText.Text = "";
}
else
{
if (remotePort < 0 || remotePort > 65535)
{
MessageBox.Show("输入的端口越界,请输入正确的端口");
PortText.Text = "";
}
else
{
TextMsg.AppendText($"Port:{remotePort}\r\n");
}
}
}
}
/// <summary>
/// 使消息面板一直显示最新的消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TextMsg_TextChanged(object sender, EventArgs e)
{
this.TextMsg.SelectionStart = this.TextMsg.Text.Length;
this.TextMsg.SelectionLength = 0;
this.TextMsg.ScrollToCaret();
}
private void SendToBtn_Click(object sender, EventArgs e)
{
if (!CheckSocketVaild() | !CheckTCPVaild())
{
return;
}
string msg = this.SendMsg.Text;
if (!string.IsNullOrEmpty(msg))
{
byte[] bytes = Encoding.UTF8.GetBytes(msg);
socket.Send(bytes);
}
this.SendMsg.Text = "";
TextMsg.AppendText($"\r\n客户端发送消息:{msg}");
}
private void ConnectBtn_Click(object sender, EventArgs e)
{
if (!CheckTCPVaild())
{
TextMsg.AppendText($"输入的IP[{remoteIPAddress}]或者端口号[{remotePort}]出错\r\n");
return;
}
Init();
try
{
IPEndPoint remoteIPEndPoint = new IPEndPoint(remoteIPAddress, remotePort);
EndPoint remoteEndPoint = (EndPoint)remoteIPEndPoint;
socket.ReceiveTimeout = 15 * 1000;
socket.SendTimeout = 15 * 1000;
socket.BeginConnect(remoteEndPoint, OnConnect, socket);
}
catch
{
socket?.Close();
socket = null;
TextMsg.AppendText($"连接不上服务器\r\n");
}
}
/// <summary>
/// 客户端未连接到服务器的时候也会触发回调
/// </summary>
/// <param name="ar"></param>
private void OnConnect(IAsyncResult ar)
{
if (ar.AsyncState != null)
{
Socket s = (Socket)ar.AsyncState;
if (s.Connected)
{
s.EndConnect(ar);
th1 = new Thread(OnReceive);
th1.IsBackground = true;
th1.Start(socket);
}
else
{
socket?.Close();
socket = null;
this.Invoke(OnChangeTextMsg, $"连接不上服务器\r\n");
}
}
}
private void OnReceive(object o)
{
try
{
//同步
//while (isReceive)
//{
// socket.Receive(dataReceive);
// if (dataReceive.Length > 0)
// {
// string msg = Encoding.UTF8.GetString(dataReceive);
// this.Invoke(OnChangeTextMsg, $"\r\n服务器返回消息:{msg}");
// }
//}
//异步
socket.BeginReceive(dataReceive, 0, dataReceive.Length, SocketFlags.None, OnReceiveAsync, socket);
}
catch (Exception e)
{
this.Invoke(OnChangeTextMsg, $"连接不上服务器,错误原因[{e.Message}],[{e.StackTrace}]\r\n");
socket?.Close();
}
}
private void OnReceiveAsync(IAsyncResult ar)
{
if (ar.AsyncState != null)
{
Socket s = (Socket)ar.AsyncState;
if (s.Connected)
{
s.EndReceive(ar);
if (dataReceive.Length > 0)
{
string msg = Encoding.UTF8.GetString(dataReceive);
this.Invoke(OnChangeTextMsg, $"\r\n服务器返回消息:{msg}");
dataReceive = new byte[1024];
socket.BeginReceive(dataReceive, 0, dataReceive.Length, SocketFlags.None, OnReceiveAsync, socket);
}
}
}
}
private void DisconnectBtn_Click(object sender, EventArgs e)
{
if (!CheckSocketVaild() || !CheckTCPVaild())
{
return;
}
byte[] bytes = Encoding.UTF8.GetBytes("close");
socket.Send(bytes);
socket?.Close();
this.Invoke(OnChangeTextMsg, $"\r\n客户端关闭");
}
/// <summary>
/// 检查合法性
/// </summary>
/// <returns></returns>
private bool CheckTCPVaild()
{
if (remoteIPAddress == null || remotePort <= 0)
{
return false;
}
return true;
}
private bool CheckSocketVaild()
{
if (socket == null)
{
return false;
}
return true;
}
private void OnKeyDown_MsgSend(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
SendToBtn_Click(sender, e);
}
}
}
}
服务端:
界面代码:
namespace ServerWinform
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.TextMsg = new System.Windows.Forms.RichTextBox();
this.SendMsg = new System.Windows.Forms.TextBox();
this.SendTo = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// TextMsg
//
this.TextMsg.Location = new System.Drawing.Point(12, 12);
this.TextMsg.Name = "TextMsg";
this.TextMsg.Size = new System.Drawing.Size(776, 387);
this.TextMsg.TabIndex = 0;
this.TextMsg.Text = "";
this.TextMsg.TextChanged += new System.EventHandler(this.TextMsg_TextChanged);
//
// SendMsg
//
this.SendMsg.Location = new System.Drawing.Point(12, 415);
this.SendMsg.Name = "SendMsg";
this.SendMsg.Size = new System.Drawing.Size(695, 23);
this.SendMsg.TabIndex = 1;
this.SendMsg.KeyDown += new System.Windows.Forms.KeyEventHandler(this.SendMsg_KeyDown);
//
// SendTo
//
this.SendTo.Location = new System.Drawing.Point(713, 415);
this.SendTo.Name = "SendTo";
this.SendTo.Size = new System.Drawing.Size(75, 23);
this.SendTo.TabIndex = 2;
this.SendTo.Text = "发送";
this.SendTo.UseVisualStyleBackColor = true;
this.SendTo.Click += new System.EventHandler(this.SendTo_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.SendTo);
this.Controls.Add(this.SendMsg);
this.Controls.Add(this.TextMsg);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private RichTextBox TextMsg;
private TextBox SendMsg;
private Button SendTo;
}
}
执行代码:
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Text;
namespace ServerWinform
{
public partial class Form1 : Form
{
private int localPort = 30081;
private Socket socket;
private Socket newSocket = null;
private Thread th1;
private Thread th2;
public Form1()
{
InitializeComponent();
Init();
}
private void Init()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localIPEndPoint = new IPEndPoint(IPAddress.Any, localPort);
socket.Bind(localIPEndPoint);
socket.Listen(20);
th1 = new Thread(Listen);
th1.IsBackground = true;
th1.Start(socket);
}
private void OnChangeTextMsg(string msg)
{
this.TextMsg.AppendText(msg);
}
private void Listen(object o)
{
while (true)
{
newSocket = socket.Accept();
string clientName = newSocket.RemoteEndPoint.ToString();
this.Invoke(OnChangeTextMsg, $"\r\n{clientName} 连接成功");
th2 = new Thread(ServerRecMsg);
isReceive = true;
th2.IsBackground = true;
th2.Start(newSocket);
}
}
private bool isReceive = true;
private void ServerRecMsg(object o)
{
try
{
Socket newSocket = (Socket)o;
while (isReceive)
{
byte[] bytes = new byte[1024];
int byteLength = newSocket.Receive(bytes);
if (bytes.Length > 0)
{
string msg = Encoding.UTF8.GetString(bytes);
if (!string.IsNullOrEmpty(msg))
{
this.Invoke(OnChangeTextMsg, $"\r\n接收到客户端信息:{msg}");
if (msg == "close")
{
//客户端关闭
isReceive = false;
newSocket.Close();
this.Invoke(OnChangeTextMsg, $"\r\n客户端关闭");
}
}
}
}
}
catch (Exception e)
{
//客户端关闭
isReceive = false;
newSocket.Close();
this.Invoke(OnChangeTextMsg, $"\r\n客户端关闭");
}
}
private void TextMsg_TextChanged(object sender, EventArgs e)
{
this.TextMsg.SelectionStart = this.TextMsg.Text.Length;
this.TextMsg.SelectionLength = 0;
this.TextMsg.ScrollToCaret();
}
private void SendTo_Click(object sender, EventArgs e)
{
if (newSocket == null || !newSocket.Connected)
{
return;
}
string msg = this.SendMsg.Text;
if (!string.IsNullOrEmpty(msg))
{
byte[] bytes = Encoding.UTF8.GetBytes(msg);
newSocket.Send(bytes);
}
this.SendMsg.Text = "";
this.Invoke(OnChangeTextMsg, $"\r\n发送给客户端信息:{msg}");
}
private void SendMsg_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
SendTo_Click(sender, e);
}
}
}
}