我正在自学tcp套接字,,遇到了个问题,就是文件传输完后,文件总是少kb的现象,做过几次,都是这样,不知道代码哪里有错,希望各位高手帮我看看,谢谢了!!!(我是自学的,有好多地方还不是蛮懂,希望顺便帮我解释一下!)
好了,这是我的代码----
////服务端
private void button1_Click(object sender, System.EventArgs e)
{
if(this.openFileDialog1.ShowDialog()==DialogResult.OK)
{
this.textBox1.Text=this.openFileDialog1.FileName;//选择一个传送的文件
}
td=new Thread(new ThreadStart(jt));
td.Start();
}
Socket so;
private void jt()
{
TcpListener tcp=new TcpListener(IPAddress.Parse("192.168.1.2"),2000);
tcp.Start();
so=tcp.AcceptSocket();
if(so.Connected)
{
FileStream file=new FileStream(this.textBox1.Text,FileMode.Open,FileAccess.Read);
BinaryReader bina=new BinaryReader(file);
byte[] b=new byte[1024];
bool a=true;
while(a)
{
int i=bina.Read(b,0,1024);
if(i>0)
{
so.Send(b,i,SocketFlags.None);
}
else
{
a=false;
bina.Close();
file.Close();
tcp.Stop();
this.textBox1.Text="ok";
td.Abort();
}
}
}
//接受端
Thread tr;
private void button2_Click(object sender, System.EventArgs e)
{
TcpClient t=new TcpClient();
t.Connect(IPAddress.Parse("192.168.1.2"),2000);
net=t.GetStream();
tr=new Thread(new ThreadStart(js));
tr.Start();
}
private void js()
{
byte[] b=new byte[1024];
FileStream f=new FileStream("c:\\x",FileMode.OpenOrCreate,FileAccess.Write);//保存为x这个文件
BinaryWriter bi=new BinaryWriter(f);
bool k=true;
while(k)
{
int z=net.Read(b,0,b.Length);
if(z>0)
{
bi.Write(b,0,z);
}
else
{
k=false;
bi.Close();
f.Close();
net.Close();
tr.Abort();
}
}
}
//补冲一下::本人对c#有极其浓厚的兴趣,可惜找不到一个老师指点,希望哪位高手可以加我qq375403293,指点本菜鸟一二。
给你一个例子吧。发到你QQ邮箱了。
问题已经找到。
jt() 这个函数中下面语句,在发送完成后应该将so 关闭。即在file.Close();后添加一句
so.Close(); 就可以了。原因:so.Send 并不是同步过程,调用这个函数,只是将数据写入了TCP的发送缓冲区,TCP 自身有一个线程定期将发送缓冲区中的数据发送出去。如果不关闭Socket就直接关闭TCP,那么最后存在于发送缓冲区中的数据将有可能发送不出去。所以必须在停止TCP之前关闭Socket,以便将发送缓冲区中的数据全部发送出去。
另外你的代码不够简洁(我没时间一一帮你改过来)而且还有一些错误,比如
1. 在其他线程操作界面控件却不进行同步操作。多线程如何操作界面见下面博客
http://www.cnblogs.com/xlfj521/archive/2007/09/12/890508.html
2. 在线程内部结束本线程只需退出循环就可以,不需要调用Thread.Abort。
while (a)
{
int i = bina.Read(b, 0, 1024);
if (i > 0)
{
so.Send(b, i, SocketFlags.None);
}
else
{
a = false;
bina.Close();
file.Close();
so.Close(); //在此处关闭socket
tcp.Stop();
//this.textBox1.Text = "ok";
td.Abort();
}
}
调用一下flush.