通过套接字在c#中传输半个文件?

时间:2015-04-29 01:34:28

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

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

我的代码在这里 服务器端

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.";
        }
    }


}

请有人帮助我

1 个答案:

答案 0 :(得分:0)

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

int receivedBytesLen = clientSock.Receive(clientData);

documentation说:

  

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

Receive的调用是获取当前可用的所有字节。可能是发件人还没有发送所有字节,或者您的网络堆栈没有收到它们并使它们可用。

为了可靠地发送和接收数据,接收方必须知道以下两种情况之一:它预期有多少字节,或者有一些标记值表示,"那是" s所有人,伙计们。"您无法依靠单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部分)。博客文章讨论了流,但概念与套接字相同。