通信基本流程:
服务端:
创建一个用于监听连接的Socket对象
用指定的ip地址和端口建立一个EndPoint对象(相当于Socket的端点)
用Socket的Bind()方法绑定EndPoint
用Socket的Listen()方法开始监听
接收到客户端的连接,用Socket的Accept()创建一个新的用于和客户端进行通信的Socket
通信结束关闭Socket
客户端:
建立一个Socket对象
用指定的ip地址和端口建立一个EndPoint对象(相当于Socket的端点)
用Socket对象的Connect()方法(EndPoint为参数)向服务器发出连接请求
如果连接成功,就用Socket对象的Send()方法向服务器发送信息
用Socket对象的Send()方法接收信息
通信结束关闭Socket
服务端界面:
服务端界面设计源码
namespace SocketString { partial class Form1 { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要修改 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.textBox1 = new System.Windows.Forms.TextBox(); this.textBox2 = new System.Windows.Forms.TextBox(); this.button3 = new System.Windows.Forms.Button(); this.textBox3 = new System.Windows.Forms.TextBox(); this.textBox4 = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // button1 // this.button1.Location = new System.Drawing.Point(315, 28); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 0; this.button1.Text = "开始监听"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // // button2 // this.button2.Location = new System.Drawing.Point(425, 28); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(75, 23); this.button2.TabIndex = 1; this.button2.Text = "停止监听"; this.button2.UseVisualStyleBackColor = true; // // textBox1 // this.textBox1.Location = new System.Drawing.Point(27, 28); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(100, 21); this.textBox1.TabIndex = 2; this.textBox1.Text = "127.0.0.1"; // // textBox2 // this.textBox2.Location = new System.Drawing.Point(158, 28); this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(100, 21); this.textBox2.TabIndex = 3; this.textBox2.Text = "8081"; // // button3 // this.button3.Location = new System.Drawing.Point(532, 206); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(75, 23); this.button3.TabIndex = 6; this.button3.Text = "发送消息"; this.button3.UseVisualStyleBackColor = true; this.button3.Click += new System.EventHandler(this.button3_Click); // // textBox3 // this.textBox3.Location = new System.Drawing.Point(51, 76); this.textBox3.Multiline = true; this.textBox3.Name = "textBox3"; this.textBox3.Size = new System.Drawing.Size(463, 98); this.textBox3.TabIndex = 7; // // textBox4 // this.textBox4.Location = new System.Drawing.Point(51, 206); this.textBox4.Multiline = true; this.textBox4.Name = "textBox4"; this.textBox4.Size = new System.Drawing.Size(463, 116); this.textBox4.TabIndex = 8; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 450); this.Controls.Add(this.textBox4); this.Controls.Add(this.textBox3); this.Controls.Add(this.button3); this.Controls.Add(this.textBox2); this.Controls.Add(this.textBox1); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.Button button3; private System.Windows.Forms.TextBox textBox3; private System.Windows.Forms.TextBox textBox4; } }
服务端后台逻辑源码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace SocketString { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //定义回调:解决跨线程访问问题 private delegate void SetTextValueCallBack(string strValue); //定义接收客户端发送消息的回调 private delegate void ReceiveMsgCallBack(string strReceive); //声明回调 private SetTextValueCallBack setCallBack; //声明 private ReceiveMsgCallBack receiveCallBack; //定义回调:给ComboBox控件添加元素 private delegate void SetCmbCallBack(string strItem); //声明 private SetCmbCallBack setCmbCallBack; //定义发送文件的回调 private delegate void SendFileCallBack(byte[] bf); //声明 private SendFileCallBack sendCallBack; //用于通信的Socket Socket socketSend; //用于监听的SOCKET Socket socketWatch; //将远程连接的客户端的IP地址和Socket存入集合中 Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>(); //创建监听连接的线程 Thread AcceptSocketThread; //接收客户端发送消息的线程 Thread threadReceive; /// <summary> /// 开始监听 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { //当点击开始监听的时候 在服务器端创建一个负责监听IP地址和端口号的Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //获取ip地址 IPAddress ip = IPAddress.Parse(this.textBox1.Text.Trim()); //创建端口号, EndPoint对象 IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(this.textBox2.Text.Trim())); //绑定IP地址和端口号 socketWatch.Bind(point); this.textBox3.AppendText("监听成功" + " "); //开始监听:设置最大可以同时连接多少个请求 socketWatch.Listen(10); //实例化回调 setCallBack = new SetTextValueCallBack(SetTextValue); receiveCallBack = new ReceiveMsgCallBack(ReceiveMsg); //setCmbCallBack = new SetCmbCallBack(AddCmbItem); //创建线程 AcceptSocketThread = new Thread(new ParameterizedThreadStart(StartListen)); AcceptSocketThread.IsBackground = true; AcceptSocketThread.Start(socketWatch); } /// <summary> /// 等待客户端的连接,并且创建与之通信用的Socket /// </summary> /// <param name="obj"></param> private void StartListen(object obj) { Socket socketWatch = obj as Socket; while (true) { //等待客户端的连接,并且创建一个用于通信的Socket socketSend = socketWatch.Accept(); //获取远程主机的ip地址和端口号 strIp = socketSend.RemoteEndPoint.ToString(); dicSocket.Add(strIp, socketSend); //this.listBox1.Invoke(setCmbCallBack, strIp); string strMsg = "远程主机:" + socketSend.RemoteEndPoint + "连接成功"; //使用回调 textBox3.Invoke(setCallBack, strMsg); //定义接收客户端消息的线程 Thread threadReceive = new Thread(new ParameterizedThreadStart(Receive)); threadReceive.IsBackground = true; threadReceive.Start(socketSend); } } string strIp; /// <summary> /// 服务器给客户端发送消息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { try { string strMsg = this.textBox4.Text.Trim(); byte[] buffer = Encoding.Default.GetBytes(strMsg); List<byte> list = new List<byte>(); list.Add(0); list.AddRange(buffer); //将泛型集合转换为数组 byte[] newBuffer = list.ToArray(); //获得用户选择的IP地址 string ip = strIp; dicSocket[ip].Send(newBuffer); } catch (Exception ex) { MessageBox.Show("给客户端发送消息出错:" + ex.Message); } //socketSend.Send(buffer); } /// <summary> /// 服务器端不停的接收客户端发送的消息 /// </summary> /// <param name="obj"></param> private void Receive(object obj) { Socket socketSend = obj as Socket; while (true) { //客户端连接成功后,服务器接收客户端发送的消息 byte[] buffer = new byte[2048]; //实际接收到的有效字节数 int count = socketSend.Receive(buffer); if (count == 0)//count 表示客户端关闭,要退出循环 { break; } else { string str = Encoding.Default.GetString(buffer, 0, count); string strReceiveMsg = "接收:" + socketSend.RemoteEndPoint + "发送的消息:" + str + " "; textBox3.Invoke(receiveCallBack, strReceiveMsg); } } } /// <summary> /// 停止监听 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { socketWatch.Close(); socketSend.Close(); //终止线程 AcceptSocketThread.Abort(); threadReceive.Abort(); } /// <summary> /// 回调委托需要执行的方法 /// </summary> /// <param name="strValue"></param> private void SetTextValue(string strValue) { this.textBox3.AppendText(strValue + " "); } private void ReceiveMsg(string strMsg) { this.textBox3.AppendText(strMsg + " "); } } }
客户端界面
客户端设计源码
namespace SocketStringServer { partial class Form1 { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要修改 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void InitializeComponent() { this.textBox4 = new System.Windows.Forms.TextBox(); this.textBox3 = new System.Windows.Forms.TextBox(); this.button3 = new System.Windows.Forms.Button(); this.textBox2 = new System.Windows.Forms.TextBox(); this.textBox1 = new System.Windows.Forms.TextBox(); this.button2 = new System.Windows.Forms.Button(); this.button1 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // textBox4 // this.textBox4.Location = new System.Drawing.Point(134, 256); this.textBox4.Multiline = true; this.textBox4.Name = "textBox4"; this.textBox4.Size = new System.Drawing.Size(463, 116); this.textBox4.TabIndex = 15; // // textBox3 // this.textBox3.Location = new System.Drawing.Point(134, 126); this.textBox3.Multiline = true; this.textBox3.Name = "textBox3"; this.textBox3.Size = new System.Drawing.Size(463, 98); this.textBox3.TabIndex = 14; // // button3 // this.button3.Location = new System.Drawing.Point(598, 386); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(75, 23); this.button3.TabIndex = 13; this.button3.Text = "发送消息"; this.button3.UseVisualStyleBackColor = true; this.button3.Click += new System.EventHandler(this.button3_Click); // // textBox2 // this.textBox2.Location = new System.Drawing.Point(241, 78); this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(100, 21); this.textBox2.TabIndex = 12; this.textBox2.Text = "8081"; // // textBox1 // this.textBox1.Location = new System.Drawing.Point(110, 78); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(100, 21); this.textBox1.TabIndex = 11; this.textBox1.Text = "127.0.0.1"; // // button2 // this.button2.Location = new System.Drawing.Point(508, 78); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(75, 23); this.button2.TabIndex = 10; this.button2.Text = "断开连接"; this.button2.UseVisualStyleBackColor = true; this.button2.Click += new System.EventHandler(this.button2_Click); // // button1 // this.button1.Location = new System.Drawing.Point(398, 78); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 9; this.button1.Text = "连接"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 450); this.Controls.Add(this.textBox4); this.Controls.Add(this.textBox3); this.Controls.Add(this.button3); this.Controls.Add(this.textBox2); this.Controls.Add(this.textBox1); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.TextBox textBox4; private System.Windows.Forms.TextBox textBox3; private System.Windows.Forms.Button button3; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button1; } }
客户端后台逻辑源码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace SocketStringServer { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //定义回调 private delegate void SetTextCallBack(string strValue); //声明 private SetTextCallBack setCallBack; //定义接收服务端发送消息的回调 private delegate void ReceiveMsgCallBack(string strMsg); //声明 private ReceiveMsgCallBack receiveCallBack; //创建连接的Socket Socket socketSend; //创建接收客户端发送消息的线程 Thread threadReceive; /// <summary> /// 连接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { try { socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ip = IPAddress.Parse(this.textBox1.Text.Trim()); socketSend.Connect(ip, Convert.ToInt32(this.textBox2.Text.Trim())); //实例化回调 setCallBack = new SetTextCallBack(SetValue); receiveCallBack = new ReceiveMsgCallBack(SetValue); this.textBox3.Invoke(setCallBack, "连接成功"); //开启一个新的线程不停的接收服务器发送消息的线程 threadReceive = new Thread(new ThreadStart(Receive)); //设置为后台线程 threadReceive.IsBackground = true; threadReceive.Start(); } catch (Exception ex) { MessageBox.Show("连接服务端出错:" + ex.ToString()); } } /// <summary> /// 接收服务器发送的消息 /// </summary> private void Receive() { try { while (true) { byte[] buffer = new byte[2048]; //实际接收到的字节数 int r = socketSend.Receive(buffer); if (r == 0) { break; } else { //判断发送的数据的类型 if (buffer[0] == 0)//表示发送的是文字消息 { string str = Encoding.Default.GetString(buffer, 1, r - 1); this.textBox3.Invoke(receiveCallBack, "接收远程服务器:" + socketSend.RemoteEndPoint + "发送的消息:" + str + " "); } } } } catch (Exception ex) { MessageBox.Show("接收服务端发送的消息出错:" + ex.ToString()); } } private void SetValue(string strValue) { this.textBox3.AppendText(strValue + " "); } /// <summary> /// 客户端给服务器发送消息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { try { string strMsg = this.textBox4.Text.Trim(); byte[] buffer = new byte[2048]; buffer = Encoding.Default.GetBytes(strMsg); int receive = socketSend.Send(buffer); } catch (Exception ex) { MessageBox.Show("发送消息出错:" + ex.Message); } } private void Form1_Load(object sender, EventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; } /// <summary> /// 断开连接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { //关闭socket socketSend.Close(); //终止线程 threadReceive.Abort(); } } }
直接复制粘贴,有些我也不懂,百度出来的,留个记录,希望能帮到大家