c#:发送文件,混合成功文件和损坏的文件

时间:2015-01-31 11:02:46

标签: c# visual-studio file tcp ip

我在互联网上进行一些研究之后编写了该代码,以便通过同一网络的计算机发送文件。但是,有时它会发送文件损坏或质量低(如果文件是图片)。你能看看吗? 注意:我只想发送10MB大小的文件。

  

服务器

class Server
{
    IPEndPoint end;
    Socket sock;

    public Server()
    {
        end = new IPEndPoint(IPAddress.Any, 5656);
        sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
        sock.Bind(end);
    }

    public static string path;
    public static string MsgCurrent = "Stopped";

    public void StartServer()
    {
        try
        {
            MsgCurrent = "Starting...";
            sock.Listen(100);
            MsgCurrent = "Works and looks for files";
            Socket clientSock = sock.Accept();
            byte[] clientData = new byte[1024 * 1024 * 10]; //count per byte
            int receivedByteLen = clientSock.Receive(clientData);
            MsgCurrent = "Receiving file ...";
            int fNameLen = BitConverter.ToInt32(clientData, 0);
            string fName = Encoding.ASCII.GetString(clientData, 4, fNameLen);
            BinaryWriter write = new BinaryWriter(File.Open(path + "/" + fName, FileMode.Append));
            write.Write(clientData, 4 + fNameLen, receivedByteLen - 4 - fNameLen);
            MsgCurrent = "Saving file....";
            write.Close();
            clientSock.Close();
            MsgCurrent = "The file was received";
        }
        catch
        {
            MsgCurrent = "Error, the file was not received";
        }
    }
}
  

客户端

 class Client
{
    public static string ipsendf;//added
    public static string MsgCurrent = "Idle";
    public static void SendFile(string fName)
    {
        try
        {
            IPAddress ip = IPAddress.Parse(ipsendf); //127.0.0.1 in "" as string
            IPEndPoint end = new IPEndPoint(ip, 5656);
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

            string path = "";
            fName = fName.Replace("\\", "/");
            while (fName.IndexOf("/") > -1)
            {
                path += fName.Substring(0, fName.IndexOf("/") + 1);
                fName = fName.Substring(fName.IndexOf("/") + 1);
            }
            byte[] fNameByte = Encoding.ASCII.GetBytes(fName);
            if (fNameByte.Length > 10 * 1024 * 1024) //count per byte
            {
                //MsgCurrent = "File is greater than 850 kb";
                MsgCurrent = "File is greater than 10MB";
                return;
            }
            MsgCurrent = "Buffering...";
            byte[] fileData = File.ReadAllBytes(path + fName);
            byte[] clientData = new byte[4 + fNameByte.Length + fileData.Length];
            byte[] fNameLen = BitConverter.GetBytes(fNameByte.Length);
            fNameLen.CopyTo(clientData, 0);
            fNameByte.CopyTo(clientData, 4);
            fileData.CopyTo(clientData, 4 + fNameByte.Length);
            MsgCurrent = "Connecting to server ...";
            sock.Connect(end);
            MsgCurrent = "File sending ...";
            sock.Send(clientData);

            MsgCurrent = "Disconnecting...";
            sock.Close();
            MsgCurrent = "The file was sent ..";
        }
        catch (Exception ex)
        {
            //do nothing
        }
    }
}

1 个答案:

答案 0 :(得分:0)

套接字的默认接收大小为8,192字节(for reference)。因此,从您的代码看起来在服务器上,您只需要读取消息的前8,192个字节。

您可以增加缓冲区大小以匹配您分配的10 MB clientData缓冲区的大小,例如,某些位于.Accept()之后和Receive()之前的位置。

clientSock.ReceiveBufferSize = 1024 * 1024 * 10;

或者,通过检查是否还有剩余内容可以读取并继续填充本地缓冲区。你可能会在本地网络上获得潜在的大量消息,但一般来说,通常以块的形式进行这种消息。

此外,您在服务器中写入文件时使用FileMode.Append,而我原本以为您需要FileMode.Create。否则,如果您发送两次相同的文件,您将获得一个20MB的文件,而不是一个10MB的文件。