一、简介
本文主要参考相关网页,进行设计,实现简单的基于WinForm的Socket TCP协议 实现端到端(服务器与客户端)图片传输。相关网址为
https://www.cnblogs.com/wuzhang/p/wuzhang20141119.html
https://blog.csdn.net/z5976749/article/details/40743487
本文知识的主要继承是来自我的上一篇博客:
C#.网络编程 Socket基础(一)Socket TCP协议 实现端到端(服务器与客户端)简单字符串通信https://blog.csdn.net/xpj8888/article/details/83383355
二、知识准备以及其注意点
知识准备:
本位主要基于C#,WinForm,Socket类,来实现端到端的图片传输。关于WinForm的快速入门,参考:
C#图形界面入门 Winform https://jingyan.baidu.com/article/17bd8e5233c09f85aa2bb84d.html
注意点(由于首次应用Winform,对基本的细节做一些笔记):
1、Form1_Load默认加载:
2、必须用this.button1.Click += new System.EventHandler(this.button1_Click)。若是用this.button1.Click += button1_Click;
移动控件button1后,this.button1.Click += button1_Click会不见。
3、良好的设计习惯是,必须先放控件,后设计代码逻辑。
三、完整的代码如下
服务器:
1、Form.cs[设计]:
2、Form.cs(主要用来处理控件的逻辑):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SocketServer_SendImage
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//Form1_Load表示默认的加载,相当于初始化。
private void Form1_Load(object sender, EventArgs e)
{
lab_pro.Text = "接收:0/100";
//button1.Text = "BBBBB";
}
/// <summary>
/// 开启服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
//MessageBox.Show(lab_pro.Text);
button1.Text = "监听中...";
button1.Enabled = false;
Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint hostIpEndPoint = new IPEndPoint(IPAddress.Parse("1.1.1.2"), 8888);
//设置接收数据缓冲区的大小
byte[] b = new byte[4096];
receiveSocket.Bind(hostIpEndPoint);
//监听
receiveSocket.Listen(2);
//接受客户端连接
Socket hostSocket = receiveSocket.Accept();
//如何确定该数组大小
MemoryStream fs = new MemoryStream();
int length = 0;
//每次只能读取小于等于缓冲区的大小
while ((length = hostSocket.Receive(b)) > 0)
{
fs.Write(b, 0, length);
if (progressBar1.Value < 100)
{
progressBar1.Value++;
lab_pro.Text = "接收:" + progressBar1.Value + "/100";
}
}
progressBar1.Value = 100;
lab_pro.Text = "接收:" + progressBar1.Value + "/100";
fs.Flush();
Bitmap Img = new Bitmap(fs);
Img.Save(@"reveive.jpg", ImageFormat.Png);
//关闭写文件流
fs.Close();
//关闭接收数据的Socket
hostSocket.Shutdown(SocketShutdown.Receive);
hostSocket.Close();
//关闭发送连接
receiveSocket.Close();
//}
}
}
}
3、Form.Designer.cs(主要用来设计控件的属性,外观、颜色、事件记录啊等等)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SocketServer_SendImage
{
public partial class Form1: Form
{
/// <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.progressBar1 = new System.Windows.Forms.ProgressBar();
this.lab_pro = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// button1
//
this.button1.ForeColor = System.Drawing.Color.Red;
this.button1.Location = new System.Drawing.Point(194, 120);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(199, 72);
this.button1.TabIndex = 0;
this.button1.Text = "开启服务\r\n";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// progressBar1
//
this.progressBar1.Location = new System.Drawing.Point(79, 234);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(427, 44);
this.progressBar1.TabIndex = 1;
//
// lab_pro
//
this.lab_pro.Font = new System.Drawing.Font("宋体", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.lab_pro.Location = new System.Drawing.Point(220, 195);
this.lab_pro.Name = "lab_pro";
this.lab_pro.Size = new System.Drawing.Size(158, 27);
this.lab_pro.TabIndex = 2;
this.lab_pro.Text = "接收:0/100";
this.lab_pro.UseWaitCursor = true;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(599, 428);
this.Controls.Add(this.lab_pro);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "服务器";
this.ResumeLayout(false);
}
#endregion
private Button button1;
private ProgressBar progressBar1;
private Label lab_pro;
}
}
4、Server.cs(系统文件的入口程序,简单的工程程序,一般不用修改这个)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SocketServer_SendImage
{
static class Server
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
客户端(Client):
1、Form1.cs[设计]
2、Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SocketClient_SendImage
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static Socket sendsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
OpenFileDialog openFileDialog1 = new OpenFileDialog();
Byte[] imgByte = new byte[1024];
/// <summary>
/// 打开本地文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btm_scane_Click(object sender, EventArgs e)
{
btm_scane.Text = "已经打开";
this.openFileDialog1.Filter = "Image Files(*.BMP;*.JPG;*.GIF;*.PNG)|*.BMP;*.JPG;*.GIF;*.PNG" + "|All Files (*.*)|*.*";
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
string path = this.openFileDialog1.FileName;
lab_path.Text = path;
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
imgByte = new Byte[fs.Length];
fs.Read(imgByte, 0, imgByte.Length);
fs.Close();
}
catch (Exception)
{
}
}
}
/// <summary>
/// 向服务器发送数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_send_Click(object sender, EventArgs e)
{
//实例化socket
IPEndPoint ipendpiont = new IPEndPoint(IPAddress.Parse("1.1.1.2"), 8888);
sendsocket.Connect(ipendpiont);
MessageBox.Show("服务器IP:" + sendsocket.RemoteEndPoint);
sendsocket.Send(imgByte);
sendsocket.Shutdown(System.Net.Sockets.SocketShutdown.Send);
sendsocket.Close();
sendsocket.Dispose();
}
}
}
3、Form.Designer.cs
namespace SocketClient_SendImage
{
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.btn_send = new System.Windows.Forms.Button();
this.btm_scane = new System.Windows.Forms.Button();
this.lab_path = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// btn_send
//
this.btn_send.Location = new System.Drawing.Point(316, 199);
this.btn_send.Name = "btn_send";
this.btn_send.Size = new System.Drawing.Size(75, 23);
this.btn_send.TabIndex = 0;
this.btn_send.Text = "发送";
this.btn_send.UseVisualStyleBackColor = true;
this.btn_send.Click += new System.EventHandler(this.btn_send_Click);
//
// btm_scane
//
this.btm_scane.Location = new System.Drawing.Point(296, 118);
this.btm_scane.Name = "btm_scane";
this.btm_scane.Size = new System.Drawing.Size(125, 23);
this.btm_scane.TabIndex = 1;
this.btm_scane.Text = "浏览";
this.btm_scane.UseVisualStyleBackColor = true;
this.btm_scane.Click += new System.EventHandler(this.btm_scane_Click);
//
// lab_path
//
this.lab_path.AutoSize = true;
this.lab_path.Location = new System.Drawing.Point(68, 60);
this.lab_path.Name = "lab_path";
this.lab_path.Size = new System.Drawing.Size(65, 12);
this.lab_path.TabIndex = 2;
this.lab_path.Text = "未发送图片";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(728, 433);
this.Controls.Add(this.lab_path);
this.Controls.Add(this.btm_scane);
this.Controls.Add(this.btn_send);
this.Name = "Form1";
this.Text = "Server";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btn_send;
private System.Windows.Forms.Button btm_scane;
private System.Windows.Forms.Label lab_path;
}
}
四、效果
查看桌面的图片、Sever工程文件 Bin/Debug/reveive.jpg,进行对比