在TCP发送断点期间影响结果

时间:2015-05-20 13:37:59

标签: c# tcp sendfile

我正在撰写的客户端/服务器应用程序出现问题。其目的是在客户端中发送特定目录的文件,并将它们发送到服务器上的目录。

我用foreach获取文件,但是当我在foreach的开头放置一个断点并继续直到我发送所有文件时,我将所有这些文件全部放在我的服务器中,当我删除断点时重新运行我的应用程序,我的服务器只接收部分文件,我不知道为什么。

我不确定,但我认为这是一个线程问题,但不知道如何解决它。

服务器:

dummy_df.loc[:, (dummy_df != '0%').any()]

客户端:

static void Main(string[] args)
{
     try
      {

            TcpListener listen = new TcpListener(3003);
            TcpClient client;
            int bufferSize = 1024;
            NetworkStream netStream = null;
            int bytesRead = 0;
            int allBytesRead = 0;

            // Start listening
            listen.Start();

            // Accept client
            client = listen.AcceptTcpClient();


            StreamReader reader = new StreamReader(client.GetStream());

            netStream = client.GetStream();
            string fileName;
            bool endOfSend=false;
           do
            {
                fileName = reader.ReadLine();

                // Read length of incoming data
                byte[] length = new byte[4];

                bytesRead = netStream.Read(length, 0, 4);
                int dataLength = BitConverter.ToInt32(length, 0);

                // Read the data
                int bytesLeft = dataLength;
                byte[] data = new byte[dataLength];


                    while (bytesLeft > 0)
                    {

                        int nextPacketSize = (bytesLeft > bufferSize) ? bufferSize : bytesLeft;

                        bytesRead = netStream.Read(data, allBytesRead, nextPacketSize);
                        allBytesRead += bytesRead;
                        bytesLeft -= bytesRead;

                    }                  

                allBytesRead = 0;
                bytesLeft = 0;
                bytesRead = 0;

                // Save file to desktop
                Console.WriteLine("File {0} received.", fileName);
                File.WriteAllBytes(@"C:\Users\toto2\Desktop\" + fileName, data);

            } while (!endOfSend);
            netStream.Close();
            client.Close();
            Console.ReadLine();
        }
        catch (Exception ex)
        {
            Console.WriteLine("File Receiving fail." + ex.Message);
        }
    }

感谢任何人都会尽力帮助我。

2 个答案:

答案 0 :(得分:1)

您可能希望从服务器向客户端实施并确认已收到1个文件。然后指示客户端发送下一个文件。据我所知,你只是一次发送所有文件。以下是确认的简单实现。您应该能够为您的场景采取相关部分。

//
/*   Server Program    */

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

public class serv {
    public static void Main() {
    try {
        IPAddress ipAd = IPAddress.Parse("172.21.5.99");
         // use local m/c IP address, and 
         // use the same in the client

/* Initializes the Listener */
        TcpListener myList=new TcpListener(ipAd,8001);

/* Start Listeneting at the specified port */        
        myList.Start();

        Console.WriteLine("The server is running at port 8001...");    
        Console.WriteLine("The local End point is  :" + 
                          myList.LocalEndpoint );
        Console.WriteLine("Waiting for a connection.....");

        Socket s=myList.AcceptSocket();
        Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);

        byte[] b=new byte[100];
        int k=s.Receive(b);
        Console.WriteLine("Recieved...");
        for (int i=0;i<k;i++)
            Console.Write(Convert.ToChar(b[i]));

        ASCIIEncoding asen=new ASCIIEncoding();
        s.Send(asen.GetBytes("The string was recieved by the server."));
        Console.WriteLine("\nSent Acknowledgement");
/* clean up */            
        s.Close();
        myList.Stop();

    }
    catch (Exception e) {
        Console.WriteLine("Error..... " + e.StackTrace);
    }    
    }

}

---------------------------------------------------------------------------

/*       Client Program      */

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Sockets;


public class clnt {

    public static void Main() {

        try {
            TcpClient tcpclnt = new TcpClient();
            Console.WriteLine("Connecting.....");

            tcpclnt.Connect("172.21.5.99",8001);
            // use the ipaddress as in the server program

            Console.WriteLine("Connected");
            Console.Write("Enter the string to be transmitted : ");

            String str=Console.ReadLine();
            Stream stm = tcpclnt.GetStream();

            ASCIIEncoding asen= new ASCIIEncoding();
            byte[] ba=asen.GetBytes(str);
            Console.WriteLine("Transmitting.....");

            stm.Write(ba,0,ba.Length);

            byte[] bb=new byte[100];
            int k=stm.Read(bb,0,100);

            for (int i=0;i<k;i++)
                Console.Write(Convert.ToChar(bb[i]));

            tcpclnt.Close();
        }

        catch (Exception e) {
            Console.WriteLine("Error..... " + e.StackTrace);
        }
    }

}

答案 1 :(得分:1)

你有一个混合二进制/文本协议。那可能很痛苦。 StreamReader缓冲部分流。它需要的不仅仅是它作为一个字符串立即返回。你不能把它和其他读者混在一起。

抛弃所有这些代码并使用更高级别的通信机制。例如,带有MTOM的WCF用于二进制流。或HTTP。

如果您不愿意使用BinaryReader广告BinaryWriter。它们相当容易使用。

请注意,当您读取长度时,您假设所有4个字节都将在一次读取中到达。这个假设是错误的。