socket实现服务端文件夹下载功能
1、客户端发送下载文件夹的请求
2、服务端接收到请求的文件目录(相对目录)
3、服务端遍历目录发送目录及文件
4、客户端接收服务端发送来的文件
目前代码已经写出来了,但是存在bug,服务端发送了2个文件,客户端把接收的2个文件写成一个文件了,部分代码如下:
服务端:
//这里递归每一个文件并传给客户端
foreach (FileInfo file in files)
{
UpLoadBatchOneFile(file, clientSocket);
Thread.Sleep(1000);
}
//单个文件上传
private void UpLoadBatchOneFile(FileInfo file, Socket client)
{
try
{
//打开文件流
FileStream fileStream = file.OpenRead();
//包的数量:这个PacketCount大小不包括最后一个小于PacketSize的包。
int PacketCount = (int)(fileStream.Length / ((long)packetSize));
//最后一个包的大小
int LastDataPacket = (int)(fileStream.Length - ((long)(packetSize * PacketCount)));
//获得客户端节点对象
IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
//发送[根目录名]到客户端
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(rootFolder));
//发送[文件名]到客户端
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.FullName.Replace(replaceString,"")));
//发送[包的大小]到客户端
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(packetSize.ToString()));
//发送[包的总数量]到客户端
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(PacketCount.ToString()));
//发送[最后一个包的大小]到客户端
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(LastDataPacket.ToString()));
//文件大小
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(file.Length.ToString()));
//数据包
byte[] data = new byte[packetSize];
//开始循环发送数据包
for (int i = 0; i < PacketCount; i++)
{
//从文件流读取数据并填充数据包
fileStream.Read(data, 0, data.Length);
//发送数据包
TransferFiles.SendVarData(client, data);
//进度条值的显示
//this.pbUpload.PerformStep();
}
//如果还有多余的数据包,则应该发送完毕!
if (LastDataPacket != 0)
{
data = new byte[LastDataPacket];
fileStream.Read(data, 0, data.Length);
TransferFiles.SendVarData(client, data);
}
//关闭套接字
//client.Close();
//server.Close();
//关闭文件流
fileStream.Close();
string msg = "客户端:" + clientep.Address.ToString() + "于[" + DateTime.Now.ToString() + "]下载文件:【" + txtFileSaveDir.Text + "\" + file.Name + "】\r\n";
LogWrite.Write(Application.StartupPath + "\\Log", DateTime.Now.ToString("yyyyMMdd") + ".txt", msg);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//点击下载按钮
private void btnDownload_Click(object sender, EventArgs e)
{
if (txtUploadDir.Text != "")
{
string requestDirName = txtRequestDownPath.Text;
//开启接收数据线程
Thread TempThread = new Thread(new ParameterizedThreadStart(this.SendRequest));
TempThread.IsBackground = true;
TempThread.Start(requestDirName);
}
else
{
MessageBox.Show("请先选择下载文件要存放的路径");
}
}
//发送下载请求
private void SendRequest(object requestDirName)
{
Form.CheckForIllegalCrossThreadCalls = false;
this.pbUpload.Value = 0;
serverIP = txtServerIP.Text;
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(serverIP), serverPort);//指向远程服务端节点
downReqSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建套接字
downReqSocket.Connect(ipep);//连接到发送端
TransferFiles.SendVarData(downReqSocket, System.Text.Encoding.Unicode.GetBytes("downloadFolderRequest"));//发送[downloadRequest]到客户端
TransferFiles.SendVarData(downReqSocket, System.Text.Encoding.Unicode.GetBytes(requestDirName.ToString()));//发送[根目录名]到客户端
//开始接收根目录名
string rootFolder = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(downReqSocket));
//downReqSocket.Close();
if (!Directory.Exists(txtUploadDir.Text + rootFolder))
{
Directory.CreateDirectory(txtUploadDir.Text + rootFolder);
}
//获得[文件名]
string SendFileName = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(downReqSocket));
//获得[包的大小]
string bagSize = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(downReqSocket));
//获得[包的总数量]
int bagCount = int.Parse(System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(downReqSocket)));
//获得[最后一个包的大小]
string bagLast = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(downReqSocket));
//获得[文件大小]
string fileSize = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(downReqSocket));
CreateDir(SendFileName);//根据传入的文件夹+文件名创建文件夹
//创建一个新文件
string fileFullName = txtUploadDir.Text + "\" + SendFileName;
FileStream MyFileStream = new FileStream(fileFullName, FileMode.Create, FileAccess.Write);
txtFileProcessSize.Text = "0M/" + CommonModule.TransferFiles.returnFileSize(Convert.ToInt32(fileSize));
//已发送包的个数
int SendedCount = 0;
int currentFileSize = 0;
while (true)
{
byte[] data = TransferFiles.ReceiveVarData(downReqSocket);
if (data.Length == 0)
{
this.pbUpload.Value = 100;
break;
}
else
{
SendedCount++;
currentFileSize += data.Length;
//将接收到的数据包写入到文件流对象
MyFileStream.Write(data, 0, data.Length);
txtFileProcessSize.Text = CommonModule.TransferFiles.returnFileSize(Convert.ToInt32(currentFileSize)) + "/" + CommonModule.TransferFiles.returnFileSize(Convert.ToInt32(fileSize));
this.pbUpload.PerformStep();
}
}
this.txtStatus.Text = "文件下载完毕!";
//关闭文件流
MyFileStream.Close();
//关闭套接字
downReqSocket.Close();
}