c# socket服务器端多线程分段传输文件,客户端多线程接收

nzzb1985 2010-05-24 04:06:55
我需要将文件都放在服务器端,客户端发送请求到服务器。服务器根据请求使用多线程把文件发给客户端,客户端也使用多线程接收到文件后,组合成1个文件。
要求用socket实现,下载速度要比用ftp快!!!
我的思路有,但就是不知道客户端的线程怎么接收到服务器端的线程,比如说客户端的线程1接收服务器端的线程1的数据,客户端的线程2接收服务器端的线程2的数据。。。。
谁能帮我下,最好有源码··谢谢了!!!!
...全文
613 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
niulei 2011-09-25
  • 打赏
  • 举报
回复
单的还没用搞定!
hexian1989 2011-06-16
  • 打赏
  • 举报
回复
请问楼上各位用单线程时速度能到多少啊?服务器和客户端都在局域网内,我弄得程序速度最大只到2M多,除了使用多线程外怎么提高速度啊?
nzzb1985 2010-05-25
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 deknight 的回复:]
mark下下吧
[/Quote]

mark?什么意思??不懂
deknight 2010-05-25
  • 打赏
  • 举报
回复
mark下下吧
nzzb1985 2010-05-25
  • 打赏
  • 举报
回复
我在多线程的发送方法里面加上了
private static Mutex mut = new Mutex();
mut.WaitOne(); 和 mut.ReleaseMutex();
但是在运行的时候发现服务器端用多线程发送,客户端用单线程接收的时候,客户端怎么只能收到1个线程里面的数据呢?也就是一半的数据。
这是怎么回事?
nzzb1985 2010-05-25
  • 打赏
  • 举报
回复
我在用多线程发送的时候发现2个线程同时访问1个方法的时候会报错,怎么避免呢?
是用锁码?用锁的话不是和单线程差不多了吗?
itrefer 2010-05-24
  • 打赏
  • 举报
回复
byte偏移一下空出前几个位置放置编号
多线程接收不一定能提高速度
nzzb1985 2010-05-24
  • 打赏
  • 举报
回复
能说的清楚点吗?怎么向这个结构赋值,怎么解析?
上面的这个好像是在为head和body赋值呢?
你说的是传输的时候还是传byte数组,不同的是数组是按这样的结构定义的?
skep99 2010-05-24
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 nzzb1985 的回复:]
你说的是传输的时候传的不是一个byte数组,而是传一个结构?
客户端在接收的时候也是接收一个结构?
是这个意思吗?
[/Quote]

不是

是两边定义同样的结构
发的这方按这个结构定义,收的这方按照这个结构解析


public class msg
{

byte[] head;
byte[] body;

public msg(byte[] bytes)
{
head = new byte[32];
body = new byte[bytes.Length - 32];
Array.Copy(bytes, head, 32);
Array.Copy(bytes, 32, body, 0, bytes.Length - 32);
}
}



nzzb1985 2010-05-24
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 littlelee 的回复:]
关注!
只做过单线程发送文件,没有做过多线程!
不地单线程用数据流的方式发送数据也能把带宽占满!
[/Quote]

单线程的已经实现了,但是老板他要求用多线程的,没办法
nzzb1985 2010-05-24
  • 打赏
  • 举报
回复
你说的是传输的时候传的不是一个byte数组,而是传一个结构?
客户端在接收的时候也是接收一个结构?
是这个意思吗?
skep99 2010-05-24
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 nzzb1985 的回复:]
那怎么在data包里面写入编号。然后在客户端怎么再把编号读取出来呢?不知道用什么方法啊
[/Quote]

多线程的话,每次只发一个包,定义一个结构,包头+包体,然后赋值

取的时候也要定义一个相同的结构,这样才能取出来
LittleLee 2010-05-24
  • 打赏
  • 举报
回复
关注!
只做过单线程发送文件,没有做过多线程!
不地单线程用数据流的方式发送数据也能把带宽占满!
nzzb1985 2010-05-24
  • 打赏
  • 举报
回复
那怎么在data包里面写入编号。然后在客户端怎么再把编号读取出来呢?不知道用什么方法啊
skep99 2010-05-24
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 nzzb1985 的回复:]
你的意思是把包的编号和文件都放到包里面,包的前32位写入的是包的编号,后面的才是文件的内容。
在客户端组合的时候根据包的内容截取前32位后,用循环把文件的内容写到一起?

不过这样的话有个问题:我是用线程调用循环的Send方法,有3个线程的话,用for循环的i作为编号的话好像不能唯一标示出包,难道用线程编号和for循环的i一起作为包的编号?加的话怎么用FileStream的Read方法加呢?……
[/Quote]

包的编号要事先用循环生成好,不要在发送循环里取,可能会重复
接收速度取决于带宽,单线程足以.
nzzb1985 2010-05-24
  • 打赏
  • 举报
回复
这是我在c/s页面的单线程的读取发送方法。在这里面应该怎么改呢?改成1个可以被线程循环调用的读取发送方法。

private void StartSend()
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipip = new IPEndPoint(IPpoint.Address, 6666);
socket.Connect(ipip);
FileInfo EzoneFile = new FileInfo(file);
//打开文件流
FileStream EzoneStream = EzoneFile.OpenRead();
//包的大小
int PacketSize = int.Parse("6000");
//包的数量
int PacketCount = (int)(EzoneStream.Length / ((long)PacketSize));
//最后一个包的大小
int LastDataPacket = (int)(EzoneStream.Length - ((long)(PacketSize * PacketCount)));

//发送[文件名]到客户端
CommonModule.EzoneModule.SendVarData(socket, System.Text.Encoding.Unicode.GetBytes(EzoneFile.Name));
//数据包
byte[] data = new byte[PacketSize];
//开始循环发送数据包
for (int i = 0; i < PacketCount; i++)
{
//从文件流读取数据并填充数据包
EzoneStream.Read(data, 0, data.Length);
//发送数据包
CommonModule.EzoneModule.SendVarData(socket, data);
}

//如果还有多余的数据包,则应该发送完毕!
if (LastDataPacket != 0)
{
data = new byte[LastDataPacket];
EzoneStream.Read(data, 0, data.Length);
CommonModule.EzoneModule.SendVarData(socket, data);
}
//关闭套接字

socket.Close();

}
nzzb1985 2010-05-24
  • 打赏
  • 举报
回复
你的意思是把包的编号和文件都放到包里面,包的前32位写入的是包的编号,后面的才是文件的内容。
在客户端组合的时候根据包的内容截取前32位后,用循环把文件的内容写到一起?

不过这样的话有个问题:我是用线程调用循环的Send方法,有3个线程的话,用for循环的i作为编号的话好像不能唯一标示出包,难道用线程编号和for循环的i一起作为包的编号?加的话怎么用FileStream的Read方法加呢?

还有就是我在客户端到底是用单线程接收,还是用多个线程接收。哪个速度快?
skep99 2010-05-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 nzzb1985 的回复:]
给每个包编号??我这46.4 MB的文件就有800多个包啊,每个包都编个号的话,到时候传几个G的文件那包不是太多了吗?
我的服务器端传送用的是Socket的Send方法,客户端接收用的是Socket的Receive方法。
2个方法都是int的返回值,包的编号放到哪?
[/Quote]

800个包还多?你看看p2p的软件,下载一个视频需要多少个包

先定义包,包分包头和包体
包头定义编号,比如32位,int的型的应该够用了
33位起是包体
nzzb1985 2010-05-24
  • 打赏
  • 举报
回复
给每个包编号??我这46.4 MB的文件就有800多个包啊,每个包都编个号的话,到时候传几个G的文件那包不是太多了吗?
我的服务器端传送用的是Socket的Send方法,客户端接收用的是Socket的Receive方法。
2个方法都是int的返回值,包的编号放到哪?
skep99 2010-05-24
  • 打赏
  • 举报
回复
比ftp速度快倒不一定,ftp也可以实现多点续传

给每个包编号,多线程发送,到目的地再组包
加载更多回复(1)

110,533

社区成员

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

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

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