如何多次发送文件
How to send file more then once
有两个C# 项目:一个项目用于客户端,另一个项目用于服务器。第一步是 运行 服务器,然后选择一个目标文件夹,然后到 运行 客户端项目,选择一些 text.txt 发送到服务器的目标文件夹。
只有客户端可以向服务器发送文件
演示:
1.choosing file target 2.client sends
+------------+
| tar folder | <---------------- text.txt
+------------+
这很好用,但我希望它每隔几分钟自动发送一次 text.txt,所以我添加了 while(true)
循环和 Thread.Sleep(10000)
,但它总是给出异常。我的意思是,它不允许我发送多次。
这里是客户端 class 我正在尝试放置一个 while 循环 :
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)//browse btn
{
string n;
byte[] b1;
TcpClient client;
OpenFileDialog op;
Stream s;
StreamWriter sw;
op = new OpenFileDialog();
if (op.ShowDialog() == DialogResult.OK)
{
string t = textBox1.Text;
t = op.FileName;
FileInfo fi = new FileInfo(textBox1.Text = op.FileName);
n = fi.Name + "." + fi.Length;
client = new TcpClient("127.0.0.1", 8100);//"127.0.0.1", 5055
sw = new StreamWriter(client.GetStream());
s = client.GetStream();
b1 = File.ReadAllBytes(op.FileName);
// s = client.GetStream();
while (true)
{
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
//sw.Close();
s.Close();//added by me
Thread.Sleep(18000);
}
sw.Flush();
client.Close();
// label2.Text = "File Transferred....";
}
}
服务器class:
public Form1()
{
InitializeComponent();
}
string rd;
byte[] b1;
string v;
int m=20;//number of byts
TcpListener list;
TcpClient client;
int port = 8100;//5050
int port1 = 8100;//5055
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
private void button1_Click(object sender, EventArgs e)//browse button
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = folderBrowserDialog1.SelectedPath;
list = new TcpListener(localAddr, port1);
list.Start();
Thread incoming_connection = new Thread(ic);
incoming_connection.Start();
}
}
private void ic()
{
client = list.AcceptTcpClient();
Stream s = client.GetStream();
b1 = new byte[m];
s.Read(b1,0, b1.Length);
MessageBox.Show("pathh "+textBox1.Text);
File.WriteAllBytes(textBox1.Text+"\flag.txt", b1);// the left side us the name of the written file
//list.Stop();
//client.Close();
// label1.Text = "File Received......";
}
private void Form2_Load(object sender, EventArgs e)
{
list = new TcpListener(localAddr, port);
// TcpListener list = new TcpListener(port);
list.Start();
TcpClient client = list.AcceptTcpClient();
MessageBox.Show("Client trying to connect");
StreamReader sr = new StreamReader(client.GetStream());
rd = sr.ReadLine();
v = rd.Substring(rd.LastIndexOf('.') + 1);
m = int.Parse(v);
// list.Stop();
// client.Close();
}
尝试更改为:
while (true)
{
using (var client = new TcpClient("127.0.0.1", 8100))//"127.0.0.1", 5055
using (var sw = new StreamWriter(client.GetStream()))
using (var s = client.GetStream())
{
b1 = File.ReadAllBytes(op.FileName);
// s = client.GetStream();
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
}
Thread.Sleep(18000);
}
using
语句有助于处理对象。
或者,如果您想保持连接打开,请尝试:
using (var client = new TcpClient("127.0.0.1", 8100))//"127.0.0.1", 5055
while (true)
{
using (var sw = new StreamWriter(client.GetStream()))
using (var s = client.GetStream())
{
b1 = File.ReadAllBytes(op.FileName);
// s = client.GetStream();
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
}
Thread.Sleep(18000);
}
好的,这是你的问题:
在第一个循环中,它按预期工作正常,因为一切都已正确初始化,但在它发送第一个文件后,您调用 s.Close();
while (true)
{
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
//sw.Close();
s.Close();//added by me
Thread.Sleep(18000);
}
现在发生的事情是在第一个循环之后关闭流,然后在第二个循环中它已经 'Disposed'。
要修复移动 s.Close();跳出循环并进入断开连接按钮事件或应用程序关闭事件。
另外我建议不要使用 Thread.Sleep(interval);
这是因为睡眠会冻结您的线程,而 .NET 中的主线程用于您的界面,因此冻结该线程非常糟糕。
像之前一样创建一个新线程post:
using System.Threading;
Stream s;
byte[] b1;
TcpClient client;
OpenFileDialog op;
StreamWriter sw;
Thread thread = new Thread(sendFile);
string fn;
string n;
threadExit = false;
Int32 interval = 18000;
public Form1()
{
InitializeComponent();
}
private void Form1_OnLoad(object sender,EventArgs e) {
op = new OpenFileDialog();
client = new TcpClient("127.0.0.1", 8100);//"127.0.0.1", 5055
sw = new StreamWriter(client.GetStream());
s = client.GetStream();
//It would be your responsibility to move this code to the proper place
//because now it tries to open the connection when your app loads
}
private void sendFile() {
while (!threadExit)
{
b1 = File.ReadAllBytes(fn);
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
Thread.Sleep(interval);
}
}
private void button1_Click(object sender, EventArgs e)
{
if (op.ShowDialog() == DialogResult.OK)
{
fn = op.FileName;
FileInfo fi = new FileInfo(textBox1.Text = op.FileName);
n = fi.Name + "." + fi.Length;
thread.Start();
}
//It would be a good idea to add an indicator to signal that another thread is trying to send the file at a set interval
}
private void Form1_Close(object sender, EventArgs e) {
s.Close();
client.Close();
threadExit = true;
Application.Exit();
}
并记住为此线程使用 try catch 块,否则如果发生异常,将无法很好地处理。另请记住,在此线程处于 运行 时关闭应用程序将使您的应用程序保持打开状态,直到您手动终止该进程,因此在应用程序关闭事件中记得终止线程。
而且关闭正在发送信号让线程退出,但最多可能需要 18 秒才能完全退出,另一种解决方案是使用 thread.Abort();但那是一个肮脏的出口,它很可能会抛出异常。
再一次记住阅读有关线程的内容,这是一个快速但糟糕的版本,它在生产环境中应该是怎样的。
有两个C# 项目:一个项目用于客户端,另一个项目用于服务器。第一步是 运行 服务器,然后选择一个目标文件夹,然后到 运行 客户端项目,选择一些 text.txt 发送到服务器的目标文件夹。 只有客户端可以向服务器发送文件
演示:
1.choosing file target 2.client sends
+------------+
| tar folder | <---------------- text.txt
+------------+
这很好用,但我希望它每隔几分钟自动发送一次 text.txt,所以我添加了 while(true)
循环和 Thread.Sleep(10000)
,但它总是给出异常。我的意思是,它不允许我发送多次。
这里是客户端 class 我正在尝试放置一个 while 循环 :
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)//browse btn
{
string n;
byte[] b1;
TcpClient client;
OpenFileDialog op;
Stream s;
StreamWriter sw;
op = new OpenFileDialog();
if (op.ShowDialog() == DialogResult.OK)
{
string t = textBox1.Text;
t = op.FileName;
FileInfo fi = new FileInfo(textBox1.Text = op.FileName);
n = fi.Name + "." + fi.Length;
client = new TcpClient("127.0.0.1", 8100);//"127.0.0.1", 5055
sw = new StreamWriter(client.GetStream());
s = client.GetStream();
b1 = File.ReadAllBytes(op.FileName);
// s = client.GetStream();
while (true)
{
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
//sw.Close();
s.Close();//added by me
Thread.Sleep(18000);
}
sw.Flush();
client.Close();
// label2.Text = "File Transferred....";
}
}
服务器class:
public Form1()
{
InitializeComponent();
}
string rd;
byte[] b1;
string v;
int m=20;//number of byts
TcpListener list;
TcpClient client;
int port = 8100;//5050
int port1 = 8100;//5055
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
private void button1_Click(object sender, EventArgs e)//browse button
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = folderBrowserDialog1.SelectedPath;
list = new TcpListener(localAddr, port1);
list.Start();
Thread incoming_connection = new Thread(ic);
incoming_connection.Start();
}
}
private void ic()
{
client = list.AcceptTcpClient();
Stream s = client.GetStream();
b1 = new byte[m];
s.Read(b1,0, b1.Length);
MessageBox.Show("pathh "+textBox1.Text);
File.WriteAllBytes(textBox1.Text+"\flag.txt", b1);// the left side us the name of the written file
//list.Stop();
//client.Close();
// label1.Text = "File Received......";
}
private void Form2_Load(object sender, EventArgs e)
{
list = new TcpListener(localAddr, port);
// TcpListener list = new TcpListener(port);
list.Start();
TcpClient client = list.AcceptTcpClient();
MessageBox.Show("Client trying to connect");
StreamReader sr = new StreamReader(client.GetStream());
rd = sr.ReadLine();
v = rd.Substring(rd.LastIndexOf('.') + 1);
m = int.Parse(v);
// list.Stop();
// client.Close();
}
尝试更改为:
while (true)
{
using (var client = new TcpClient("127.0.0.1", 8100))//"127.0.0.1", 5055
using (var sw = new StreamWriter(client.GetStream()))
using (var s = client.GetStream())
{
b1 = File.ReadAllBytes(op.FileName);
// s = client.GetStream();
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
}
Thread.Sleep(18000);
}
using
语句有助于处理对象。
或者,如果您想保持连接打开,请尝试:
using (var client = new TcpClient("127.0.0.1", 8100))//"127.0.0.1", 5055
while (true)
{
using (var sw = new StreamWriter(client.GetStream()))
using (var s = client.GetStream())
{
b1 = File.ReadAllBytes(op.FileName);
// s = client.GetStream();
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
}
Thread.Sleep(18000);
}
好的,这是你的问题:
在第一个循环中,它按预期工作正常,因为一切都已正确初始化,但在它发送第一个文件后,您调用 s.Close();
while (true)
{
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
//sw.Close();
s.Close();//added by me
Thread.Sleep(18000);
}
现在发生的事情是在第一个循环之后关闭流,然后在第二个循环中它已经 'Disposed'。
要修复移动 s.Close();跳出循环并进入断开连接按钮事件或应用程序关闭事件。
另外我建议不要使用 Thread.Sleep(interval); 这是因为睡眠会冻结您的线程,而 .NET 中的主线程用于您的界面,因此冻结该线程非常糟糕。
像之前一样创建一个新线程post:
using System.Threading;
Stream s;
byte[] b1;
TcpClient client;
OpenFileDialog op;
StreamWriter sw;
Thread thread = new Thread(sendFile);
string fn;
string n;
threadExit = false;
Int32 interval = 18000;
public Form1()
{
InitializeComponent();
}
private void Form1_OnLoad(object sender,EventArgs e) {
op = new OpenFileDialog();
client = new TcpClient("127.0.0.1", 8100);//"127.0.0.1", 5055
sw = new StreamWriter(client.GetStream());
s = client.GetStream();
//It would be your responsibility to move this code to the proper place
//because now it tries to open the connection when your app loads
}
private void sendFile() {
while (!threadExit)
{
b1 = File.ReadAllBytes(fn);
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
Thread.Sleep(interval);
}
}
private void button1_Click(object sender, EventArgs e)
{
if (op.ShowDialog() == DialogResult.OK)
{
fn = op.FileName;
FileInfo fi = new FileInfo(textBox1.Text = op.FileName);
n = fi.Name + "." + fi.Length;
thread.Start();
}
//It would be a good idea to add an indicator to signal that another thread is trying to send the file at a set interval
}
private void Form1_Close(object sender, EventArgs e) {
s.Close();
client.Close();
threadExit = true;
Application.Exit();
}
并记住为此线程使用 try catch 块,否则如果发生异常,将无法很好地处理。另请记住,在此线程处于 运行 时关闭应用程序将使您的应用程序保持打开状态,直到您手动终止该进程,因此在应用程序关闭事件中记得终止线程。
而且关闭正在发送信号让线程退出,但最多可能需要 18 秒才能完全退出,另一种解决方案是使用 thread.Abort();但那是一个肮脏的出口,它很可能会抛出异常。
再一次记住阅读有关线程的内容,这是一个快速但糟糕的版本,它在生产环境中应该是怎样的。