【问题标题】:Half file transferring in c# via socket?通过套接字在c#中传输半文件?
【发布时间】:2015-05-01 06:17:14
【问题描述】:

我正在通过中间级别的贪婪路由开发文件传输应用程序,其中文件发送到贪婪和贪婪再次将文件发送到路由器 但他的问题是有时客户端会收到完整的文件,有时会收到文件的某些部分

我的代码在这里 服务器端

IPAddress[] ipAddress = Dns.GetHostAddresses("127.0.0.1");
            IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], 5655);
            Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);


            string filePath = "";


            fileDes = fileDes.Replace("\\", "/");
            while (fileDes.IndexOf("/") > -1)
            {
                filePath += fileDes.Substring(0, fileDes.IndexOf("/") + 1);
                fileDes = fileDes.Substring(fileDes.IndexOf("/") + 1);
            }


            byte[] fileNameByte = Encoding.ASCII.GetBytes(fileDes);

            lblError.Text = "";
            lblError.Text = "Buffering ...";
            byte[] fileData = File.ReadAllBytes(filePath + fileDes);
            byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
            byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);

            fileNameLen.CopyTo(clientData, 0);
            fileNameByte.CopyTo(clientData, 4);
            fileData.CopyTo(clientData, 4 + fileNameByte.Length);

            lblError.Text = "";
            lblError.Text = "Connection to server ...";
            clientSock.Connect(ipEnd);

            lblError.Text = "";
            lblError.Text = "File sending...";
         //   System.Threading.Thread.Sleep(1000);
            clientSock.Send(clientData);
            label3.Text = clientData.Length.ToString();

            lblError.Text = "";
            lblError.Text = "Disconnecting...";
            clientSock.Close();

            lblError.Text = "";
            lblError.Text = "File transferred.";

在客户端

class DestCode
{
    IPEndPoint ipEnd;
    Socket sock;
    public DestCode()
    {
       ipEnd = new IPEndPoint(IPAddress.Any, 5656);
       sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
       sock.Bind(ipEnd);
    }
    public static string receivedPath;
    public static string curMsg = "Stopped";
    public static int res;
    public  void StartServer()
    {
        try
        {
            curMsg = "Starting...";
            sock.Listen(100);

            curMsg = "Running and waiting to receive file.";
            Socket clientSock = sock.Accept();

            byte[] clientData = new byte[1024 * 5000];

            int receivedBytesLen = clientSock.Receive(clientData);

            curMsg = "Receiving data...";

            int fileNameLen = BitConverter.ToInt32(clientData, 0);
            string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);

            BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath +"/"+ fileName, FileMode.Append)); ;
            bWrite.Write(clientData,4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
            res = receivedBytesLen;
            if (receivedPath == "")
            {
                MessageBox.Show("No Path was selected to Save the File");
            }
            curMsg = "Saving file...";

            bWrite.Close();
            clientSock.Close();
            curMsg = "File Received ...";

            StartServer();

        }
        catch (Exception ex)
        {
            curMsg = "File Receving error.";
        }
    }
}

贪婪

class ReceiverCode
{
    IPEndPoint ipEnd;
    Socket sock;
    public ReceiverCode()
    {
        ipEnd = new IPEndPoint(IPAddress.Any, 5655);
        sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
        sock.Bind(ipEnd);
    }
    public static string receivedPath;
    public static string curMsg = "Stopped";
    public static string Rout = "";
    public static int rlength = 0;
    public static string MsgStatus = "";
    public static byte[] send;
    public void StartServer()
    {
        try
        {
            curMsg = "Starting...";
            sock.Listen(100);

            curMsg = "Running and waiting to receive file.";
            Socket clientSock = sock.Accept();

            byte[] clientData = new byte[1024 * 5000];

            int receivedBytesLen = clientSock.Receive(clientData);
           System.Threading.Thread.Sleep(5000);
            rlength = receivedBytesLen;
            curMsg = "Receiving data...";

            int receive = clientSock.Receive(clientData);


            send = new byte[receivedBytesLen];
            Array.Copy(clientData, send, receivedBytesLen);
            Rout = "Start";
            clientSock.Close();
            curMsg = "Reeived & Saved file; Server Stopped.";
            StartServer();

        }
        catch (Exception ex)
        {
            curMsg = "File Receving error.";
        }
    }


}

请有人帮助我

【问题讨论】:

    标签: sockets c#-4.0 file-transfer filewriter


    【解决方案1】:

    问题是Socket.Receive 不能保证您会收到您要求的所有字节。所以你写:

    int receivedBytesLen = clientSock.Receive(clientData);
    

    documentation 说:

    如果您使用的是面向连接的 Socket,则 Receive 方法将读取尽可能多的数据,直到缓冲区的大小。

    Receive 的调用正在获取当前可用的所有字节。可能是发送方尚未发送所有字节,或者您的网络堆栈尚未收到它们并使它们可用。

    为了可靠地发送和接收数据,接收者必须知道以下两件事之一:要么它预期有多少字节,要么有一些标记值表示“伙计们,就这样”。你不能指望一个Receive 电话就能得到一切。

    传输文件时,发送方通常将文件大小作为所发送数据的前四个字节。然后,您的代码读取前四个字节(确保您获得所有四个字节)以确定大小,然后旋转一个循环,从套接字读取数据,直到收到所有预期的字节。

    类似:

    const int MaximumSize = 1000000;
    // read the first four bytes
    var sizeBytes = ReadBytesFromSocket(socket, 4);
    int size = BitConverter.ToInt32(sizeBytes);
    
    var dataBuffer = ReadBytesFromSocket(socket, size);
    // you now have your data
    
    byte[] ReadBytesFromSocket(Socket socket, int size)
    {
        var buff = new byte[size];
        int totalBytesRead = 0;
    
        while (totalBytesRead < size)
        {
            int bytesRead = socket.Receive(buff, totalBytesRead, size-totalBytesRead, SocketFlags.None);
            if (bytesRead == 0)
            {
                // nothing received. The socket has been closed.
                // maybe an error.
                break;
            }
            totalBytesRead += bytesRead
        }
        return buff;
    }
    

    有关更多信息,请参阅我在 reading streams 上的博客文章(以及链接的第 1 和第 2 部分)。博客文章讨论了流,但概念与套接字相同。

    【讨论】:

      猜你喜欢
      • 2017-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多