TCP 发送数据速度如何控制?

yifawu100 2013-09-01 10:55:10
TCP 发送数据速度如何控制?
如果发送端不停的用Send函数发送数据,每次发送512字节,可是到了第44次发送后,程序就好像停下来了,什么也发不了,是不是发送的速度要求自己控制啊?要如何控制啊。

发送端:
byte[] buffers = new byte[Constants.RECORDSIZE];
FileStream fs = File.Open(filename, FileMode.Open);
int n = 0;
int sd,sds,allsend,ti;
allsend = 0; //已发送的字节数
ti = 0; //发送次数
while (true)
{
n = fs.Read(buffers,0, Constants.RECORDSIZE); //从文件流中读取数据到发送缓冲区
sds = 0;
while (n>0) //要求把n个字节的数据发出去
{
sd = sender.Send(buffers, sds,n-sds, SocketFlags.None);
ti++; //这是发送次数,
allsend += sd;
SendMessage(mainWindow, 2000, n, ti);
sds += sd;
if (sds == n)
break;

}

if (n == 0) //文件流读取完毕,退出发送过程
break;
}

fs.Close();
...全文
1651 52 打赏 收藏 转发到动态 举报
写回复
用AI写文章
52 条回复
切换为时间正序
请发表友善的回复…
发表回复
yifawu100 2014-09-09
  • 打赏
  • 举报
回复
后来在程序中发送数据包,接受端收到一个包后马上发一个TCP的确认包,。。。,对发送速度进行了控制,结果速度快了很多,也很少出现程序无反应的现象。
jshi123 2013-09-10
  • 打赏
  • 举报
回复
谢谢你的反馈
yifawu100 2013-09-10
  • 打赏
  • 举报
回复
改进后的发送数据进程: public void SendFileData() { startsend = true; Socket datasocket;//发送数据的套接字 IPAddress ipAddress = IPAddress.Parse(remoteip); remoteEP = new IPEndPoint(ipAddress, port); datasocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); datasocket.SendBufferSize = Constants.BUFFERSIZE; try { datasocket.Connect(remoteEP); } catch (ArgumentNullException ane) { Console.WriteLine("ArgumentNullException : {0}", ane.ToString()); errorstr = ane.ToString(); } catch (SocketException se) { Console.WriteLine("SocketException : {0}", se.ToString()); errorstr = se.ToString(); } catch (Exception e) { Console.WriteLine("Unexpected exception : {0}", e.ToString()); errorstr = e.ToString(); } if (!datasocket.Connected) { startsend = false;//this process will exit return; } string sreceid = receid.ToString();//receid是服务器操作的文件ID索引,并把它发给服务器的接收数据进程 while (sreceid.Length < 8) sreceid = "0" + sreceid; string s1 = SLOADDATA + sreceid + sreceid; //Senddata(s1);//inform server start receive data precess Senddata(s1, datasocket); filestream.Position = filestart; //文件续传位置,从服务器查询所得 byte[] buffers = new byte[Constants.RECORDSIZE]; int n, sds, sd,ti=0,allsend=0; datasocket.SendTimeout = 600;//发送超时设置 while (true) //2 { n = filestream.Read(buffers, 0, Constants.RECORDSIZE); //从文件流中读取数据到发送缓冲区 sds = 0; while (n > 0) //要求把n个字节的数据发出去 { sd = 0; try { sd = datasocket.Send(buffers, sds, n - sds, SocketFlags.None); } catch //出现发送阻塞时,超时退出 { datasocket.Shutdown(SocketShutdown.Both); datasocket.Close(); startsend = false;//告知控制进程,发送已经终止了,要准备新的发送进程will exit the send process break; } Thread.Sleep(1); ti++; //这是发送次数, // sender.Receive(receidbuf, 4, SocketFlags.None); allsend += sd; SendMessage(mainWindow, 2000, twice, ti);//发送进度到主窗口 sds += sd; if (sds == n) break; }//while (n>0) if (n == 0) //数据读完了 { datasocket.Shutdown(SocketShutdown.Both); datasocket.Close(); //isok = true; startsend = false;//will exit the send process } if (startsend == false) break; }// while (true) //2 } 服务器控制进程,接收进程其实是同一个进程中的两个函数,根据连接命令字来调用。
yifawu100 2013-09-10
  • 打赏
  • 举报
回复
改进后的发送控制进程: public void UploadFileTCP() { time1 = DateTime.Now; filestream = File.Open(filename, FileMode.Open); filesize = filestream.Length; isok = false; Connet(); if (connected == false) { return; } int len1 = serverpath.Length; string slen1 = len1.ToString(); while (slen1.Length < 8) { slen1 = "0" + slen1; } string slen2 = filesize.ToString(); while (slen2.Length < 8) //file size only less then 100M,otherwize will throw a exception { slen2 = "0" + slen2; } // slen1 =length of serverpath string s1 = SLOADFILE + slen1 + slen2 + serverpath; //slen2 =size of the file Senddata(s1);//通知服务器启动控制进程 waiting for server ready byte[] receidbuf = new byte[8];//8字节 long 型 //接受服务器文件ID号 int recebytes = sender.Receive(receidbuf, 8, SocketFlags.None); if (recebytes != 8) return; receid = BitConverter.ToInt64(receidbuf, 0); filestart = 0; long com1 = 1000;//发送给服务器的命令,询问是否ready?并要求返回文件大小值 byte[] bytecom1 = BitConverter.GetBytes(com1); int r = 0; while (true) { //start send data process while (true) { if (!startsend)//发送进程是否在运行,有就算了 sleep,没有就 break出去,启动 break; else Thread.Sleep(10); } try { sender.Send(bytecom1, bytecom1.Length, SocketFlags.None); } catch { break; } r = 0; try { r = sender.Receive(receidbuf, receidbuf.Length, SocketFlags.None); } catch(Exception e) { break;//出现异常可能是服务器接收完毕并退出控制进程了,break退出就可以了 } if (r != 8) continue; //There is a error filestart = BitConverter.ToInt64(receidbuf,0); if (filestart < 0 || filestart > filesize) continue; if (filestart == filesize) break; Thread sendfilethread = new Thread(SendFileData); startsend = true; twice++; sendfilethread.Start();//启动发送进程 Thread.Sleep(100); } filestream.Close(); CloseSocket(); SendMessage(mainWindow, 2001, 1, 1);//通知主窗口发送接束 }
yifawu100 2013-09-10
  • 打赏
  • 举报
回复
小结一下:
后来看了下FTP传输协议,它采用两个连接,一个连接是控制,一个连接是数据传送。分别在20,21两个端口。
我模仿FTP,一个连接是控制,另外一个连接是传数据,而且都是同一个端口,控制部分不断监控发送进程是否在发送,发送进程一旦发送开始阻塞(设置500MM为超时发送),就退出这个发送过程,并关闭这个连接,此时,控制进程询问服务器:已经收到了多少数据?并强制服务器关闭接收数据的进程。客户端控制进程根据接收到的文件位置,开启新的发送进程,发送进程连接服务器,并传送一个文件ID给服务器,连接时启动服务器新的接收进程。 直到发送完毕。
测试接果,如果一次只发送一个文件,速度比不上专门的FTP传输工具。 如果同时发送多个文件,或者将文件分割为多个小文件,速度比FTP还快。
jshi123 2013-09-05
  • 打赏
  • 举报
回复
确实是有问题,现在是无法连接了。 另外我看到你的21端口是MS的FTP Service,不是LeapFtp,是不是它们根本就不是同一台机器啊?
yifawu100 2013-09-05
  • 打赏
  • 举报
回复
我QQ是76530848,随时联系我
yifawu100 2013-09-05
  • 打赏
  • 举报
回复
TO:jshi123
你帮我试一下吧,我在服务器上打开了pcattcp
,端口是默认的,IP是118*140*3*213,看看如何
jshi123 2013-09-05
  • 打赏
  • 举报
回复
主要是除了你的ftp,其它好像都有问题,你不觉得可疑吗? 所以建议你再多试几个tcp测试软件,或者把服务器上其它web服务也打开试下。不要猛改程序,结果是网络的问题。
yifawu100 2013-09-05
  • 打赏
  • 举报
回复
这个不关FTP的事,现在干脆这样,不停的发送,并设置发送超时,若超过500毫秒,就重连,断点续传,不知这样行不行。
jshi123 2013-09-05
  • 打赏
  • 举报
回复
能不能给我一个临时的ftp账号,我看下
yifawu100 2013-09-05
  • 打赏
  • 举报
回复
LeapFtp是客户端工具(有很多种啊),是专门上下载ftp文件的,与ftp服务器没有关系。
jshi123 2013-09-04
  • 打赏
  • 举报
回复
23楼的程序是很简单普通的程序,如果它运行有问题,就有可能是你的线路有问题了。 你的路由器上有没启用什么流量控制的功能?检查下MTU的设置是多少? 你可以下载一些tcp测试软件测试下,比如netcat,Hercules,还有pcattcp,这个是做benchmark的,有很多这样的小工具,可以搜下。 你说ftp工具传很快,是什么工具,上传时候是多线程的吗?你可以用sniffer或专门的ftp monitor(也是有很多的)来看下它是怎么通信的,中间有没有断过。
jshi123 2013-09-04
  • 打赏
  • 举报
回复
你用pcattcp看下传输速度是多少?这个不需要安装的,服务器上打: pcattcp -r 客户端打: pcattcp -t ip地址 http://www.pcausa.com/Utilities/pcattcp.htm 下载在页面下部
yifawu100 2013-09-04
  • 打赏
  • 举报
回复
leapFtp软件是一个上下载ftp服务器文件的客户端,我在服务器上设置了ftp服务。 leapFtp上下载都很通顺。
yifawu100 2013-09-04
  • 打赏
  • 举报
回复
对方(香港)的网络最近升级了,速度提升了,才导致这些问题的(以前没有问题的通信程序也有问题了) 暂时只有降低程序的效率来解决问题,限制包大小及等待每个包确认,这终究不是办法
yifawu100 2013-09-04
  • 打赏
  • 举报
回复
如果线路有问题,那么用leapFtp软件又很好用呢? 对方(香港)的网络最近升级了,速度提升了,才导致这些问题的(以前没有问题的通信程序也有问题了), 但leafFtp又没有影响。 我怀疑是我的SendBuffersize 小了,默认是8K,但我每次发1K,还要服务器确认每个包,这样也会出错,每次必须小于1K,还要每发一个包等待服务器确认,就没问题。 看来也不是我的SendBuffersize小了
jshi123 2013-09-04
  • 打赏
  • 举报
回复
连pcattcp都不能运行?我觉得不可能啊,那真有可能是环境的问题。 你的服务器上除了leapFtp还有其他网络服务吗,它们正常吗? 你是怎么远程操作的,远程终端?服务器是一块网卡吗? pcattcp换到别的机器上运行试下呢?或者你找别人从其它地方运行一下pcattcp试试?
yifawu100 2013-09-04
  • 打赏
  • 举报
回复
试过了,客户端运行后就不能退出了,看来是程序没反应了
yifawu100 2013-09-03
  • 打赏
  • 举报
回复
是啊,正在学习中......
加载更多回复(32)

110,538

社区成员

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

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

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