一直有个疑问想不通,请教下:
实现网络文件传输(上传或者下载),已知FTP可以完成,但是FTP是基于TCP实现的,想找一个基于UDP开发的方法实现文件传输,不知如何实现?或者不用应用层协议,仅基于UDP实现传输,但又不知道文件如何拆分(便于传输)? 谢谢了
实现网络文件传输(上传或者下载),已知FTP可以完成,但是FTP是基于TCP实现的,想找一个基于UDP开发的方法实现文件传输,不知如何实现?或者不用应用层协议,仅基于UDP实现传输,但又不知道文件如何拆分(便于传输)? 谢谢了
调试欢乐多
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading; class UDPServer
{
private Socket server;
// private byte[] buf;
private IPAddress address;
private IPEndPoint endPoint;
//private IPHostEntry hostEntry;
private ASCIIEncoding encoding = new ASCIIEncoding(); public UDPServer()
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//hostEntry = Dns.GetHostName();
//address = hostEntry.AddressList[0];
////address = IPAddress.Parse("127.0.0.1");
////endPoint = new IPEndPoint(address, 5690);
address = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
Console.WriteLine(address.ToString());
endPoint = new IPEndPoint(address, 5690);
server.Bind(endPoint);
ThreadProcessor processor = new ThreadProcessor(server);
Thread thread = new Thread(new ThreadStart(processor.run));
thread.Start();
} public UDPServer(string host,int point){
server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
address = IPAddress.Parse(host);
endPoint = new IPEndPoint(address, 5690);
server.Bind(endPoint);
ThreadProcessor processor = new ThreadProcessor(server);
Thread thread = new Thread(new ThreadStart(processor.run));
thread.Start();
} private class ThreadProcessor
{
private Socket server;
private byte[] buffer = new byte[512];
public ThreadProcessor(Socket server)
{
this.server = server;
} public void run()
{
while (true)
{
// IPEndPoint sender = new IPEndPoint(IPAddress.Any,0);
// EndPoint remote = (EndPoint) sender; // int dataLen = server.ReceiveFrom(buffer,ref remote);
int dataLen = server.Receive(buffer);
if (dataLen > 0)
{
DateTime date = DateTime.Now;
Console.WriteLine("-------------{0}----------------",date.ToString());
Console.WriteLine("接收到的内容为:[{0}]",Encoding.ASCII.GetString(buffer,0,dataLen));
Console.WriteLine();
}
}
}
}
public static void Main(string[] args){
UDPServer server = new UDPServer();
}
}
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;public class UDPClient
{
private byte[] buffer = new byte[512];
private Socket client;
private IPAddress address;
private IPEndPoint endPoint;
private int port = 5690;
private string host = "127.0.0.1"; public UDPClient()
{
address = IPAddress.Parse(host);
endPoint = new IPEndPoint(address, port);
client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
} public UDPClient(String host, int port)
{
this.host = host;
this.port = port;
address = IPAddress.Parse(host);
endPoint = new IPEndPoint(address, port);
client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
} public int send(string text)
{
Console.WriteLine("向服务器发送的内容为:{0}", text);
int result = 0;
if (String.IsNullOrEmpty(text))
{
return 0;
} buffer = Encoding.ASCII.GetBytes(text);
long start = DateTime.Now.ToBinary();
result = client.SendTo(buffer, text.Length, SocketFlags.None, endPoint);
if (result > 0)
{
Console.WriteLine("数据发送成功!!");
long end = DateTime.Now.ToBinary();
Console.WriteLine("耗时:{0}毫秒",(end-start));
}
else
{
Console.WriteLine("数据发送失败!!");
}
return result;
} public void exit()
{
if (client != null)
{
client.Close();
}
} public static void Main(string[] args){
UDPClient client=new UDPClient("121.28.233.213",5690);
client.send("001118631172868");
client.exit();
}}
{
public short MagicNumber = 0x5446; // 'FT' 特殊标记
public PacketType PacketType; // 类型
public uint RequestId; // 会话编号 (每个下载分配一个独特编号)
public uint PacketId; // 数据包编号
public uint Length; // 数据长度
}public enum PacketType : short
{
Error = 0,
ReqDownload = 1,
AckDownload = 2, ReqPackets = 3,
AckPackets = 4, Data = 5,
Text = 6,
}当客户端发出下载请求的时候,服务端可以进行准备,并告诉客户总共会有几个包,并给当前下载一个独特编号。// 客户-要求下载文件
// 0 1 2 3
//-----------------------
// 1) 'F' 'T' 1 0 类型: 要求下载文件
// 2) 0 0 0 0 会话编号: (不使用)
// 3) 0 0 0 0 包块编号: (不使用)
// 4) 9 0 0 0 长度: 9
//--------------------------------------------------
// 5) 'h' 'e' 'l' 'l' UTF8文件名: hello.txt
// 6) 'o' '.' 't' 'x'
// 7) 't'// 服务-通知下载就绪
// 0 1 2 3
//-----------------------
// 1) 'F' 'T' 2 0 类型: 传送文件就绪
// 2) 01 F2 31 1D 会话编号: 0x1D31F201
// 3) FE 0 0 0 包块编号: 总共会有254个包
// 4) 14 0 0 0 长度: 4*4 + 9
//--------------------------------------------------
// 5) .. .. .. .. MD5: 16个字节,用来最后判断文件是否完好
// 6) .. .. .. ..
// 7) .. .. .. ..
// 8) .. .. .. ..
// 9) 'h' 'e' 'l' 'l' UTF8文件名: hello.txt
//10) 'o' '.' 't' 'x'
//11) 't'
客户准备好接收文件磁盘空间后(比如假定每个包的数据为512个字节,只有最后一个包可以小于512),开始请求下载多个数据包,比如要求数据包[0,1,2]。客户在收到一些数据包后,填入磁盘,并进行勾销。超过一定时间,还没有收到的包,比如包1,必须再次加入请求,比如如[1,3,4,5]。// 客户-要求下载包块
// 0 1 2 3
//-----------------------
// 1) 'F' 'T' 3 0 类型: 要求传送(多个)数据块
// 2) 01 F2 31 1D 会话编号: 0x1D31F201
// 3) 0 0 0 0 包块编号: (不使用)
// 4) C 0 0 0 长度: 3*4
//--------------------------------------------------
// 5) 0 0 0 0 包块编号: 0
// 6) 1 0 0 0 包块编号: 1
// 7) 2 0 0 0 包块编号: 2
// 服务-发送包块
// 0 1 2 3
//-----------------------
// 1) 'F' 'T' 5 0 类型: 传送一个数据块
// 2) 01 F2 31 1D 会话编号: 0x1D31F201
// 3) 1 0 0 0 包块编号: 1
// 4) 0 2 0 0 长度: 512
//--------------------------------------------------
// ... 数据: 512个字节
当客户收到所有的包,进行完整性校验,可以通知服务器下载完毕。
这时服务端则可以结束当前下载会话。当然,如果服务端发现客户端一段时间没有请求,也可以结束会话。
QQ软件实现的文件传输 我在网上看是基于UDP实现的HOW?
想法不错! 感觉从难易度和效果上来看 不如FTP 谢谢分享
WINFORM下实现HttpRequest能用么?