通过套接字传输文件(bir和小尺寸)

时间:2013-12-27 21:01:59

标签: c# .net sockets

你好我正在尝试实现一个服务器和客户端,可以传输任何类型和任何大小的文件,但有一个问题我以某种方式破坏文件。我尝试了很多方法,但无法弄明白。基本上我可以连接,我可以理解客户想要的文件,并可以通过套接字发送。当我尝试打开该文件时,它显示一条错误消息(尝试过winrar,mp4,avi文件)这是我的代码:

//服务器

private void Receive(string receivedFileName, string fileSize)
{
    try
    {
        int receivedBytesLen = 0;
        byte[] incomingFile = new byte[int.Parse(fileSize)];
        activity.AppendText("Preparing to download... \n");
        while (incomingFile != null && int.Parse(fileSize) > receivedBytesLen)
        {
            tempSocket.Receive(incomingFile);

            receivedBytesLen = incomingFile.Length;
            int fileNameLen = BitConverter.ToInt32(incomingFile, 0);
            File.WriteAllBytes(fileDir + "//" + receivedFileName, incomingFile);
        }
        activity.AppendText("File saved to " + fileDir + "\n");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

/////////////////////////////////////////////// ///////////////////////

//服务器选项2

private void Receive(string receivedFileName, string fileSize)
{

try
{

    byte[] incomingFile = new byte[10124 * 5000];
    activity.AppendText("Preparing to download... \n");
    BinaryWriter bWrite = new BinaryWriter(File.Open(folderBrowserDialog1.SelectedPath + "//" + receivedFileName, FileMode.Append));
    int receivedBytesLen = tempSocket.Receive(incomingFile, incomingFile.Length, 0);
    int fileNameLen = BitConverter.ToInt32(incomingFile, 0);
    //string fileName = Encoding.UTF8.GetString(incomingFile, 4, fileNameLen);

    //bWrite.Write(incomingFile, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
    while (receivedBytesLen > 0)
    {
        receivedBytesLen = tempSocket.Receive(incomingFile, incomingFile.Length, 0);
        if (receivedBytesLen == 0)
        {
            bWrite.Close();
        }
        else
        {
            bWrite.Write(incomingFile, 0, receivedBytesLen);
        }
    }
    activity.AppendText("File saved to " + fileDir + "\n");
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

}

/////////////////////////////////////////////// //////////////////////

//客户端

                private void Upload_Click(object sender, EventArgs e)
    {//Uploads selected file after clicking upload button.
        try
        {
            if (clientSocket.Connected)
            {
                byte[] buffer = new byte[1024];
                byte[] sendingFile = null;
                sendingFile = File.ReadAllBytes(openFileDialog1.FileName);
                FileInfo f = new FileInfo(openFileDialog1.FileName);
                string fileSize = f.Length.ToString();
                buffer = Encoding.Default.GetBytes(getUserName.Text + "Upload" + openFileDialog1.SafeFileName + "size" + fileSize + "end");
                clientSocket.Send(buffer);
                activityLog.AppendText("Sending File \n");
                int bytesToBeSent = sendingFile.Length;
                int bytesActuallySent = 0;
                while(bytesActuallySent < bytesToBeSent){
                bytesActuallySent += clientSocket.Send(sendingFile, bytesActuallySent, bytesToBeSent -bytesActuallySent, 0);
                }
                    activityLog.AppendText("File Sent.\n");
            }
        }
        catch(Exception ex){
            MessageBox.Show(ex.Message);
        }

    }

2 个答案:

答案 0 :(得分:0)

为了满足任何大小的文件,你需要一个选项#3,一个读取字节块直到接收到所有字节的选项,你的选项#1在2 GIG盒子上运行的3 GIG文件上不会那么好......

这是一个链接:http://www.yoda.arachsys.com/csharp/readbinary.html

我喜欢此链接中的选项#2。

然而,在他们写入memoryStream的示例中,您应该写入文件流,即目标文件。

答案 1 :(得分:0)

服务器选项#2更好。但是有一些改进

  1. 套接字接收缓冲区受OS决定,一般为8192
  2. 在客户端和服务器中使用FileStream,不要忘记在文件下载后关闭文件流
  3. 客户端:

    FileStream fileStream = new FileStream(filePath, FileMode.Open)
    byte[] buff = new byte[8192];
    do
    {
        bytesRead = fileStream.Read(buff, 0, buff.Length);              
        sock.send(dataSock, buff, bytesRead);
    }while (bytesRead > 0);
    fileStream.close();
    

    服务器:

    FileStream fileStream = new FileStream(filePath, FileMode.Open)
    do
    {
        bytesRead = sock.receive(buff, 0, buff.Lenght);
        fileStream.Write(buff, 0, bytesRead );
    }while (bytesRead > 0);
    fileStream.close();