//程序是借鉴TcpFileTransferDemo项目的来的.谢谢原作者.在BAIDU.GOOGLE里面好难找到这个代码的下载.希望大家 能跟原作者多多学习交流.成为好朋友.好的代码总是很难寻找到合适的.C#传文件源码很少.好辛苦.好感谢原作者.还有改进的地方就是可以用多线程进行大文件传送.
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms;
using System.Data; using System.IO; using System.Net; using System.Net.Sockets; using System.Threading;
namespace CSharpData { /// <summary> /// SaveFileForm 的摘要说明。 /// </summary> public class SaveFileForm : System.Windows.Forms.Form { private System.Windows.Forms.Panel panel1; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.Label label2; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Button button4; private System.Windows.Forms.Button button3; private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button1; private System.Windows.Forms.StatusBar statusBar1; /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.Container components = null;
public SaveFileForm() { // // Windows 窗体设计器支持所必需的 // InitializeComponent();
setStatusDelegate = new SetStatusDelegate(SetStatus); getSaveFileDelegate = new GetSaveFileDelegate(GetSaveFile); // // TODO: 在 InitializeComponent 调用后添加任何构造函数代码 // }
/// <summary> /// 清理所有正在使用的资源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); }
#region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.panel1 = new System.Windows.Forms.Panel(); this.textBox2 = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.textBox1 = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.button4 = new System.Windows.Forms.Button(); this.button3 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.button1 = new System.Windows.Forms.Button(); this.statusBar1 = new System.Windows.Forms.StatusBar(); this.panel1.SuspendLayout(); this.SuspendLayout(); // // panel1 // this.panel1.Controls.Add(this.textBox2); this.panel1.Controls.Add(this.label2); this.panel1.Controls.Add(this.textBox1); this.panel1.Controls.Add(this.label1); this.panel1.Controls.Add(this.button4); this.panel1.Controls.Add(this.button3); this.panel1.Controls.Add(this.button2); this.panel1.Controls.Add(this.button1); this.panel1.Location = new System.Drawing.Point(8, 16); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(272, 152); this.panel1.TabIndex = 0; // // textBox2 // this.textBox2.Location = new System.Drawing.Point(96, 64); this.textBox2.Name = "textBox2"; this.textBox2.TabIndex = 15; this.textBox2.Text = "800"; // // label2 // this.label2.Location = new System.Drawing.Point(8, 72); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(80, 16); this.label2.TabIndex = 14; this.label2.Text = "通信端口"; // // textBox1 // this.textBox1.Location = new System.Drawing.Point(96, 24); this.textBox1.Name = "textBox1"; this.textBox1.TabIndex = 13; this.textBox1.Text = "192.168.1.250"; // // label1 // this.label1.Location = new System.Drawing.Point(8, 32); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(80, 16); this.label1.TabIndex = 12; this.label1.Text = "IP地址"; // // button4 // this.button4.Location = new System.Drawing.Point(160, 104); this.button4.Name = "button4"; this.button4.Size = new System.Drawing.Size(64, 23); this.button4.TabIndex = 11; this.button4.Text = "接收文件"; this.button4.Click += new System.EventHandler(this.button4_Click); // // button3 // this.button3.Location = new System.Drawing.Point(56, 104); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(64, 23); this.button3.TabIndex = 10; this.button3.Text = "发送文件"; this.button3.Click += new System.EventHandler(this.button3_Click); // // button2 // this.button2.Location = new System.Drawing.Point(200, 64); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(64, 23); this.button2.TabIndex = 9; this.button2.Text = "停止监听"; this.button2.Click += new System.EventHandler(this.button2_Click); // // button1 // this.button1.Location = new System.Drawing.Point(200, 24); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(64, 23); this.button1.TabIndex = 8; this.button1.Text = "开始监听"; this.button1.Click += new System.EventHandler(this.button1_Click); // // statusBar1 // this.statusBar1.Location = new System.Drawing.Point(0, 191); this.statusBar1.Name = "statusBar1"; this.statusBar1.Size = new System.Drawing.Size(292, 22); this.statusBar1.TabIndex = 1; this.statusBar1.Text = "statusBar1"; // // SaveFileForm // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(292, 213); this.Controls.Add(this.statusBar1); this.Controls.Add(this.panel1); this.Name = "SaveFileForm"; this.Text = "局域网内接收文件"; this.panel1.ResumeLayout(false); this.ResumeLayout(false);
} #endregion
private void button1_Click(object sender, System.EventArgs e) { port = 0; try { port = int.Parse(textBox2.Text); if (port < 1 || port > 65535) throw new ArgumentOutOfRangeException(); } catch { MessageBox.Show("请输入有效的端口号。"); textBox2.Focus(); textBox2.SelectAll(); return; } button1.Enabled = false; button2.Enabled = true; worker = new Thread(new ThreadStart(Start)); worker.IsBackground = true; worker.Start(); }
private void button2_Click(object sender, System.EventArgs e) { try { worker.Abort(); } catch {} }
private void button3_Click(object sender, System.EventArgs e) { }
private void button4_Click(object sender, System.EventArgs e) { }
#region 程序逻辑 private Thread worker; private int port;
private void Start() { try // 捕获线程中止异常 { SetStatus("开始侦听端口"); TcpListener tcpListener = new TcpListener(IPAddress.Any, port); try // 捕获开始侦听时出现的错误,例如端口已被占用 { tcpListener.Start(); } catch (Exception e) { SetStatus("侦听端口出错:" + e.Message); InvokeCancel(); return; } try // 确保停止侦听 { SetStatus("等待传入连接中"); while (true) // 一直循环,直到线程被中止。但每次只处理一个连接 { // 没有等待传入的连接就一直等待。不使用异步模型以提高程序可读性 while (!tcpListener.Pending()) Thread.Sleep(100);
TcpClient tcpClient = tcpListener.AcceptTcpClient(); tcpClient.NoDelay = true; tcpClient.ReceiveTimeout = 30000; BinaryReader reader = new BinaryReader(tcpClient.GetStream());
try // 捕获文件传输中途出现的错误,并确保关闭连接 { string filename = reader.ReadString(); long total = reader.ReadInt64(); SetStatus("收到文件传输请求,文件名 " + filename + ",大小 " + total.ToString() + " 字节");
string saveAs = GetSaveFile(filename); if (saveAs == null) { SetStatus("操作已取消。等待下一连接中"); // finally 段会帮忙关闭连接 } else { SetStatus("接收文件中"); FileStream fs = File.Create(saveAs); try { byte[] buffer = new byte[8192]; int len; while (total > 0) { len = reader.Read(buffer, 0, 8192); if (len == 0) throw new IOException("发送方中止了连接"); fs.Write(buffer, 0, len); SetStatus("接收文件中 - 剩余 " + (total -= len).ToString() + " 字节"); } SetStatus("文件已保存至 " + saveAs + "。等待下一连接中"); } finally { fs.Close(); } } } catch (Exception e) { SetStatus("文件传输中途出错:" + e.Message); InvokeCancel(); } finally { try { reader.Close(); } catch {} try { tcpClient.Close(); } catch {} } } } finally { tcpListener.Stop(); } } catch (ThreadAbortException) { SetStatus("用户中断"); InvokeCancel(); } finally { worker = null; } } #endregion
#region 线程安全UI操作代码 private delegate void SetStatusDelegate(string status); private SetStatusDelegate setStatusDelegate; // 赋值在构造函数里
private void SetStatus(string status) { if (InvokeRequired) Invoke(setStatusDelegate, new object[] { status }); else statusBar1.Text = status; }
private void InvokeCancel() { if (InvokeRequired) Invoke(new MethodInvoker(InvokeCancel)); else { button2.Enabled = false; button1.Enabled = true; } }
private delegate string GetSaveFileDelegate(string filename); private GetSaveFileDelegate getSaveFileDelegate; // private string GetSaveFile(string filename) { if (InvokeRequired) return (string)Invoke(getSaveFileDelegate, new object[] { filename }); else { //打开要发送的文件 SaveFileDialog sfd = new SaveFileDialog(); sfd.FileName = filename; if (sfd.ShowDialog(this) == DialogResult.OK) return sfd.FileName; else return null; } } #endregion } }
|
请发表评论