首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

socket实现服务端文件夹下载效能

2013-10-12 
socket实现服务端文件夹下载功能1、客户端发送下载文件夹的请求2、服务端接收到请求的文件目录(相对目录)3、

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();
        }


[解决办法]
你的FileStream MyFileStream只存文件一次,当然只由一个文件了
[解决办法]
你客户端得到的文件大小就没用上,还有包大小和包的数量,这些信息不用在接收的时候就毫无意义。
[解决办法]
这代码基础太差了,客户端接收时很难判断和区分每个文件。

这么改吧:
1. 客户端第一次要求列出服务器文件目录
2. 收到的目录后,客户端循环下载,每次只下一个文件

热点排行