C#tcp套接字客户端服务器传输多个文件问题

C#tcp套接字客户端服务器传输多个文件问题,c#,sockets,tcp,file-transfer,C#,Sockets,Tcp,File Transfer,我有两个应用程序,一个是服务器应用程序,另一个是客户端应用程序。两者都在同一台计算机上。客户端有一个按钮。单击此按钮时,客户端开始从服务器下载文件。 问题是,有时客户端成功地接收到所有文件,但有时客户端只接收到第一个文件,然后停止传输。下面的代码有问题吗?有人能告诉我哪里错了吗?我刚刚开始这样编码。 非常感谢你的帮助。提前谢谢。 代码如下: 当用户单击客户端上的按钮时,客户端将发送从服务器下载文件的请求: //client side sendRequest("requestFiles ");

我有两个应用程序,一个是服务器应用程序,另一个是客户端应用程序。两者都在同一台计算机上。客户端有一个按钮。单击此按钮时,客户端开始从服务器下载文件。 问题是,有时客户端成功地接收到所有文件,但有时客户端只接收到第一个文件,然后停止传输。下面的代码有问题吗?有人能告诉我哪里错了吗?我刚刚开始这样编码。 非常感谢你的帮助。提前谢谢。 代码如下:

当用户单击客户端上的按钮时,客户端将发送从服务器下载文件的请求:

//client side
sendRequest("requestFiles ");
服务器将在收到令牌请求文件后为客户端准备要下载的文件

// server side
if (execmd == "requestFiles")
{
    string[] fList = Directory.GetFiles(folderDir);
    for (int i = 0; i < fList.Length; i++)
    {
        FileInfo fi = new FileInfo(fList[i]);
        string[] mDesc = new string[3];
        mDesc[0] = fi.Name;
        mDesc[1] = fi.Length.ToString();
        mDesc[2] = fi.FullName;
        string fileSend = "CommitRequest " + fi.Name + " " + fi.Length.ToString() + " " + usID + " " + mName;
        sendRequest(fileSend);
        ClientDownloadingFromServer(mDesc[2], mDesc[1], sock);
    }
    sendComment("AllUpDone");
    continue;
}
方法在客户端从服务器下载FileFromServer:

//client side
private void downloadMapFromServer(Socket s)
{        
    Socket sock = s;
    //prepare directory rootDir to store file
    System.IO.FileStream fout = new System.IO.FileStream(rootDir + "\\" + fileN, FileMode.Create, FileAccess.Write);
    NetworkStream nfs = new NetworkStream(sock);
    long size = int.Parse(fileS);
    long rby = 0;
    try
    {
        //loop till the Full bytes have been read
        while (rby < size)
        {
            byte[] buffer = new byte[1024];
            //Read from the Network Stream
            int i = nfs.Read(buffer, 0, buffer.Length);
            fout.Write(buffer, 0, (int)i);
            rby = rby + i;
        }
        fout.Close();
    }
    catch (Exception ed)
    {
        Console.WriteLine("A Exception occured in file transfer" + ed.ToString());
        MessageBox.Show(ed.Message);
    }
}
//客户端
私有void下载MapFromServer(套接字)
{        
插座插座=s;
//准备目录rootDir以存储文件
System.IO.FileStream fout=new System.IO.FileStream(rootDir+“\\”+fileN,FileMode.Create,FileAccess.Write);
NetworkStream nfs=新的NetworkStream(sock);
long size=int.Parse(文件);
长rby=0;
尝试
{
//循环,直到读取完整字节
while(rby
方法clientDownloadFromServer位于服务器端:

//server side
void ClientDownloadingFromServer(string fiPath, string fiSize, Socket s)
{
    string parm1 = fiPath;
    string parm2 = fiSize;
    try
    {
        FileInfo ftemp = new FileInfo(parm1);
        long total=ftemp.Length;
        long rdby=0 ;
        int len=0 ;
        byte[] buffed = new byte[1024] ;
        // Open the file requested for download 
        System.IO.FileStream fin = new System.IO.FileStream(parm1,FileMode.Open , FileAccess.Read) ;

        NetworkStream nfs = new NetworkStream(sock) ;

        while(rdby < total && nfs.CanWrite)
        {
             //Read from the File (len contains the number of bytes read)
             len =fin.Read(buffed,0,buffed.Length) ;
             //Write the Bytes on the Socket
             nfs.Write(buffed, 0,len);
             //Increase the bytes Read counter
             rdby=rdby+len ;    
        }
        fin.Close();
    }
}
//服务器端
void ClientDownloadingFromServer(stringfipath、stringfisize、sockets)
{
字符串parm1=fiPath;
字符串parm2=fiSize;
尝试
{
FileInfo-ftemp=新的FileInfo(parm1);
总长度=ftemp.Length;
长rdby=0;
int len=0;
字节[]缓冲=新字节[1024];
//打开请求下载的文件
System.IO.FileStream fin=new System.IO.FileStream(parm1,FileMode.Open,FileAccess.Read);
NetworkStream nfs=新的NetworkStream(sock);
而(rdby
问题与将接收字节视为文件字节或令牌字节有关。您的客户端代码正在尝试读取等于缓冲区大小的字节。服务器一个接一个地发送“CommitRequest”令牌和文件字节。假设第一个文件大小为1200字节。服务器将发送这1200字节,然后是第二个文件的“CommitRequest”,然后是第二个文件字节。现在,客户端将读取1024字节的第一个文件。然后它将读取接下来的1024个字节,但这些字节将包含第一个文件剩余的176个字节,“CommitRequest”响应来自服务器,然后是第二个文件的前几个字节。您的客户机代码只占用前176个字节,忽略下一个文件中包含数据的下一个字节


您可以通过两种方式解决此问题-或者通过确保剩余字节将被处理(这可能很棘手,因为剩余字节可能部分有“CommitRequest”响应)或者重新构建您的解决方案,使每次文件传输仅在客户请求后启动。

您是说有时您只收到一次委托,或者您收到多个提交,但只下载一个文件?提交的目的是发送文件名和文件大小,以便客户端准备从服务器接收文件,并使客户端调用下载方法。我不知道怎么检查。调试不适合我。我的问题是,例如,服务器发送2个文件,abc.txt和def.txt,但客户端只接收abc.txt,并且该文件的大小大于服务器上的abc.txt(1kb)。感谢您的回答。我想我明白你的意思了。我忘了提到问题也发生在同一组文件上。例如,服务器发送3个文件file1、file2、file3。有时客户端得到所有3个文件,但有时客户端只得到文件1。如果我这样更改它,你认为它会工作吗?客户端单击下载,服务器发送一个包含所有文件名和文件大小的字符串。客户端foreach文件名为字符串,发送带有文件名的请求令牌并调用下载方法(上面的downloadMapFromServer)。服务器接收令牌请求和文件名,然后搜索带有该文件名的文件,然后将文件发送给客户端(ClientDownloadFromServer).所以我将for命令从服务器更改为客户端。这将很难,因为我必须从字符串中获取文件名和大小。您对此有何看法?它会修正错误吗?它有效吗?Thx 4您的再次帮助。@Petemry,依我看,逐个请求每个文件的方法听起来不错,而且很简单。文件名和大小可以通过一些标记序列(如| |)来分隔,而这些标记序列在文件名中是不可能找到的(和简单的字符串。拆分将得到文件列表)。谢谢VinayC。现在,我将尝试实现这一点。但是,对于同一组文件,代码有时有效,有时无效,原因是什么?下载和上传代码有什么问题吗?如果我多次尝试下载,程序就会停止工作。例如,第一次下载文件1、文件2、第二次下载文件A、文件B、第三次。。。在第四次程序停止时,并没有崩溃,但停止了。@petemry,按照代码的方式,很难预测它什么时候能工作,什么时候不能工作。这是因为服务器代码试图一个接一个地传输文件。在客户机上,可以接收任意数量的字节集。例如,第一个f
//server side
void ClientDownloadingFromServer(string fiPath, string fiSize, Socket s)
{
    string parm1 = fiPath;
    string parm2 = fiSize;
    try
    {
        FileInfo ftemp = new FileInfo(parm1);
        long total=ftemp.Length;
        long rdby=0 ;
        int len=0 ;
        byte[] buffed = new byte[1024] ;
        // Open the file requested for download 
        System.IO.FileStream fin = new System.IO.FileStream(parm1,FileMode.Open , FileAccess.Read) ;

        NetworkStream nfs = new NetworkStream(sock) ;

        while(rdby < total && nfs.CanWrite)
        {
             //Read from the File (len contains the number of bytes read)
             len =fin.Read(buffed,0,buffed.Length) ;
             //Write the Bytes on the Socket
             nfs.Write(buffed, 0,len);
             //Increase the bytes Read counter
             rdby=rdby+len ;    
        }
        fin.Close();
    }
}