C# 在TCP发送期间,断点会影响结果

C# 在TCP发送期间,断点会影响结果,c#,tcp,sendfile,C#,Tcp,Sendfile,我正在编写的客户机/服务器应用程序有问题。它的目的是在客户端发送特定目录的文件,并将它们发送到服务器上的目录 我用foreach获取文件,但当我在foreach的开始处设置断点,然后继续发送所有文件,直到我想在服务器中发送所有文件为止。当我删除断点并重新运行应用程序时,服务器只接收部分文件,我不知道为什么 我不确定,但我想这是一个线程问题,但不知道如何解决它 服务器: static void Main(string[] args) { try {

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

我用foreach获取文件,但当我在foreach的开始处设置断点,然后继续发送所有文件,直到我想在服务器中发送所有文件为止。当我删除断点并重新运行应用程序时,服务器只接收部分文件,我不知道为什么

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

服务器:

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);
        }
    }
客户:

static void Main(string[] args)
{
try
{
    IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
    int port = 3003;

    TcpClient client = new TcpClient();
    //NetworkStream netStream;

    // Connect to server
    try
    {
        client.Connect(new IPEndPoint(ipAddress, port));
        Console.WriteLine("Connecté.....");
        SendFiles(client);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    // Clean up
    client.Close();
    Console.Read();
}
catch (Exception ex)
{
    Console.WriteLine("File Sending fail." + ex.Message);
}


}

public static  void SendFiles(TcpClient cli) {
    NetworkStream netS=cli.GetStream();

   int bufferSize = 1024;
    string[] files = Directory.GetFiles(@"C:\Users\toto\Mes Images\test");


StreamWriter writer = new StreamWriter(cli.GetStream());


foreach (string item in files)
{
    writer.WriteLine(Path.GetFileName(item));
    writer.Flush();


    // Read bytes from image
    byte[] data = File.ReadAllBytes(Path.GetFullPath(item));

    // Build the package
    byte[] dataLength = BitConverter.GetBytes(data.Length);
    byte[] package = new byte[4 + data.Length];
    dataLength.CopyTo(package, 0);
    data.CopyTo(package, 4);

    // Send to server
    int bytesSent = 0;
    int bytesLeft = package.Length;

    while (bytesLeft > 0)
    {

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

        netS.Write(package, bytesSent, nextPacketSize);
        bytesSent += nextPacketSize;
        bytesLeft -= nextPacketSize;

    }
}
writer.Close();
netS.Close();
}

谢谢你,任何能帮助我的人

您可能希望实现并确认服务器已接收到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);
        }
    }

}
//
/*服务器程序*/
使用制度;
使用系统文本;
Net系统;
使用System.Net.Sockets;
公共类服务{
公共静态void Main(){
试一试{
IPAddress ipAd=IPAddress.Parse(“172.21.5.99”);
//使用本地m/c IP地址,以及
//在客户端中使用相同的方法
/*初始化侦听器*/
TcpListener myList=新的TcpListener(ipAd,8001);
/*在指定的端口开始侦听*/
myList.Start();
WriteLine(“服务器正在端口8001上运行…”);
Console.WriteLine(“本地端点为:”+
myList.LocalEndpoint);
WriteLine(“等待连接…”);
套接字s=myList.AcceptSocket();
Console.WriteLine(“从“+s.RemoteEndPoint”接受连接);
字节[]b=新字节[100];
int k=s.Receive(b);
Console.WriteLine(“接收…”);

对于(int i=0;i您有一个混合的二进制/文本协议。这可能会很痛苦。
StreamReader
缓冲流的一部分。它需要的时间超过它作为字符串立即返回的时间。您不能将它与其他读卡器混合使用

扔掉所有这些代码,使用更高级的通信机制。例如,WCF和MTOM用于二进制流。或者HTTP

如果您不愿意使用
BinaryReader
ad
BinaryWriter
,那么它们相当容易使用


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

谢谢您的回答,我将尝试使用部分代码:虽然您的读取极不可能填满
dataLength
的缓冲区,但不能保证读取所有4个字节。您需要像循环一样进行循环对于您的主要数据(我建议您创建一个静态帮助器方法,其中传入TcpClient和所需的字节数,并返回该大小的完全填充的
byte[]
。请参阅我的
ReadFully
方法,它使用套接字而不是TcpClient,但主体是相同的)