C#SOcket传送文件加上延迟新建线程就可以正常传送。不加就不能传送。

AW 2014-09-04 12:43:39
文件1:12.exe
文件2:12.zip


下面我简单说一下代码。没看懂就去看一下下面的详细代码。辛苦了
接收端:一个非常简单的接收端。简单到不行的接收端。接收文件的缓冲区还有FileStream这两个设置的值。都大于发送过来文件的总大小。例如发送端总字节数为40万。接收端设置的值为50万字节。
发送端。一个非常简单的发送端。简单到不行的发送端。
问题就出现在这里了。如果给Connect和send之家加上一个线程暂停(1毫秒)就行。或者Connect后创建一个新线程了来执行发送都可以正常传送文件。但是不加线程暂停不创建新线程在一个线程上。那么文件就不能发送成功。

发生的现象:1,如果加上线程暂停。发送过去的40万字节的.exe形成50万字节的.exe还是可以正常运行的。但是发送的压缩文件不行.
2,如果接收端设置为正常文件大小。那三种情况都是正常的。

void aa() //这个是发送端
{
string imagePath = "D:\\12.exe";
IPAddress ip = IPAddress.Parse("192.168.1.3");
IPEndPoint ipe = new IPEndPoint(ip, 5000);
//创建Socket
Socket cSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
cSocket.Connect(ipe);
//Thread.Sleep(1); //这里到send那里加上线程暂停或者创建新线程文件都可以发送成功。
if (cSocket.Connected)
{
FileStream reader = new FileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.None);
int filelength = (int)reader.Length;
byte[] buffer = new byte[filelength]; //创建文件缓冲区
reader.Read(buffer, 0, filelength); //读取文件长度的字节添加到缓冲区
int ru =cSocket.Send(buffer, 0, filelength, SocketFlags.None);
//MessageBox.Show(cSocket.SendBufferSize.ToString());
}
//创建FileStream对象
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}



//这里是接收端
private void button1_Click(object sender, EventArgs e)
{
string path = "E://da.exe";
IPAddress ip = IPAddress.Parse("192.168.1.3");
IPEndPoint ipe = new IPEndPoint(ip, 5000);
//创建Socket
Socket cSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
cSocket.Bind(ipe);
cSocket.Listen(0);
Socket nSocket=cSocket.Accept();

//byte[] buffs1= new byte[1024];
//nSocket.Receive(buffs1);
//int Filelength = BitConverter.ToInt32(buffs1, 0);
byte[] buffs2 = new byte[50000000];
//423424
if (nSocket.Connected)
{
nSocket.Receive(buffs2, 0, buffs2.Length, SocketFlags.None);

}
using (FileStream writer = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
{
writer.Write(buffs2, 0, 50000000);
writer.Flush();
}
MessageBox.Show("完成");

}
...全文
288 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
AW 2014-09-08
  • 打赏
  • 举报
回复
结果没有人回答问题的原因,那就先这样了吧。反正只要注意缓冲区的大小这个问题就不会发生
AW 2014-09-05
  • 打赏
  • 举报
回复
引用 11 楼 sunny906 的回复:
你的这个问题出在服务端接收上,把代码改成下面的试试看
。嗯。修改为正常大小确实可以发送。下面是我的疑问。你在瞅瞅。 接收端:接收文件的缓冲区还有FileStream这两个设置的值。都大于发送过来文件的总大小。例如发送端总字节数为40万。接收端设置的值为50万字节。 如果发送端给Connect和send之家加上一个线程暂停(1毫秒就行)。或者Connect后创建一个新线程了来执行发送都可以正常传送文件。但是不加线程暂停,不创建新线程在一个线程上。那么文件就不能发送成功。 理论上不应该出现这个问题才对。
sunny906 2014-09-05
  • 打赏
  • 举报
回复
你的这个问题出在服务端接收上,把代码改成下面的试试看

            int len = 0;
            if (nSocket.Connected)
            {
                len = nSocket.Receive(buffs2, 0, buffs2.Length, SocketFlags.None);

            }
            using (FileStream writer = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                writer.Write(buffs2, 0, len);
                writer.Flush();
            }
baidu_16609983 2014-09-05
  • 打赏
  • 举报
回复
来加分的,谢谢
AW 2014-09-05
  • 打赏
  • 举报
回复
引用 3 楼 Z65443344 的回复:
不知道,也不想知道... 你还是先参考网上现成的代码,看看人家都是怎么做客户端和服务端的,不能老凭自己想象瞎写啊 你点了按钮之后,进入ACCEPT?这都什么思路. 而且数据缓冲区,定义成50000000大小,只发送一次,接收一次?? 只能说,这个代码用来做实验还行,根本用不了.
网上的很多代码执行后也是这样加上线程暂停或者新建线程就能传送。单一线程就不行。 好像这个链接的就是http://bbs.csdn.net/topics/340085446
AW 2014-09-05
  • 打赏
  • 举报
回复
引用 6 楼 sunny906 的回复:
你不能这样发送文件。你一次性读出文件,然后又一次性地发送,如果文件内容很小的话,用这种方法文件是可以发送成功的;如果文件内容比较大,这样发送肯定不会成功,因为socket发送数据是有大小限制的。最好的做法就是先定义数据包格式,然后把文件拆分成N个数据包,每次发送一个数据包,每次发送完可以设置一个时间间隔,直到数据包全部发送完成。这还只是简单的数据包发送方法,严格来说用socket发送数据还需要对数据进行校验、并判断数据是否发送成功,如果成功才继续发送下一个数据包。
谢谢提醒。咱能不能先把困扰我的为什么加上线程暂停或者新建线程就可以传送。我那个50万字节只是一个演示。就算是1字节的文件也是加线程暂停就能传送。不加就不能传送。
於黾 2014-09-05
  • 打赏
  • 举报
回复
严格来说用socket发送数据还需要对数据进行校验 -> TCP底层已经做好了数据校验和重发机制,不需要自己再做校验 不过还是需要检测一下数据包长度
sunny906 2014-09-05
  • 打赏
  • 举报
回复
你不能这样发送文件。你一次性读出文件,然后又一次性地发送,如果文件内容很小的话,用这种方法文件是可以发送成功的;如果文件内容比较大,这样发送肯定不会成功,因为socket发送数据是有大小限制的。最好的做法就是先定义数据包格式,然后把文件拆分成N个数据包,每次发送一个数据包,每次发送完可以设置一个时间间隔,直到数据包全部发送完成。这还只是简单的数据包发送方法,严格来说用socket发送数据还需要对数据进行校验、并判断数据是否发送成功,如果成功才继续发送下一个数据包。
AW 2014-09-05
  • 打赏
  • 举报
回复
引用 3 楼 Z65443344 的回复:
不知道,也不想知道... 你还是先参考网上现成的代码,看看人家都是怎么做客户端和服务端的,不能老凭自己想象瞎写啊 你点了按钮之后,进入ACCEPT?这都什么思路. 而且数据缓冲区,定义成50000000大小,只发送一次,接收一次?? 只能说,这个代码用来做实验还行,根本用不了.
开始用来做笔记的。然后就遇到这个问题了。为什么加上延迟或新创建线程就可以正常发送。单独一个线程就不行。
seaonce 2014-09-05
  • 打赏
  • 举报
回复
每次发送的包不宜超过1M,否则会造成内存泄漏。传送小文件时,问题显示不出来,一旦遇上大文件,问题就显现了。
於黾 2014-09-05
  • 打赏
  • 举报
回复
不知道,也不想知道... 你还是先参考网上现成的代码,看看人家都是怎么做客户端和服务端的,不能老凭自己想象瞎写啊 你点了按钮之后,进入ACCEPT?这都什么思路. 而且数据缓冲区,定义成50000000大小,只发送一次,接收一次?? 只能说,这个代码用来做实验还行,根本用不了.
AW 2014-09-05
  • 打赏
  • 举报
回复
人工置顶。知道的大神帮忙解释一下啊。各位版主快出来。别藏着了
AW 2014-09-04
  • 打赏
  • 举报
回复
别沉啊。知道的大神回答一下啊。虽然这个问题可以解决。但是为什么加上延迟就能传送。不加就不行。

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧