2012-06-08 116 views
0

作爲學校項目,我創建了一個FileSharing應用程序。 我將所有想要的消息發送到服務器,並且一切正常,但是當涉及到將文件上傳到服務器時,該文件絕不會是它應該的方式。我調試了應用程序,發現Socket沒有返回正確數量的字節。 我不知道這是否應該是正確的方式,但我認爲這是錯誤的。 例如,當我上傳一個小的.txt文件,並用Notepad ++打開它時,我在文件的末尾看到很多null,這意味着我正在寫更多,然後它應該被寫入。我在互聯網上搜索它,並在codeplex上找到了一個和我一樣的應用程序,但是套接字返回了正確數量的數據,即http://srf.codeplex.com/Socket.Receive()返回的數據量不正確

如果有人能幫助我,我將不勝感激。 對不起,如果英語很爛,它不是我的母語。

,處理消息並做

服務器功能接收克林特連接:

public void Brodcast() 
    { 
     tcpListener.Start(); 
     while (true) 
     { 
      try 
      { 
       ClientSocket = tcpListener.AcceptSocket(); 
       MessageReceiving(); 
      } 
      catch { } 
     } 
    } 

    public void MessageReceiving() 
    { 
     if (ClientSocket.Connected) 
     { 
      OpenPackage.MessageTypeToBytes RSMessage = new OpenPackage.MessageTypeToBytes(); 
      ClientSocket.Receive(RSMessage.MessageBytes, 512, SocketFlags.None); 
      if (RSMessage.TypeOfMessage == MessageType.Login) 
       DoLogin(); 
      else if (RSMessage.TypeOfMessage == MessageType.Download) 
       SendFile(); 
      else if (RSMessage.TypeOfMessage == MessageType.Upload) 
       ReceiveFile(); 
      else if (RSMessage.TypeOfMessage == MessageType.NConta) 
       NewAccount(); 
      else if (RSMessage.TypeOfMessage == MessageType.Search) 
       SearchResult(); 
      else if (RSMessage.TypeOfMessage == MessageType.Apagar) 
       DeleteFile(); 
     } 
    } 

服務器:

public void ReceiveFile() 
    { 
     try 
     { 
      byte[] MessageBytes = new byte[512]; 
      ClientSocket.Receive(MessageBytes, 512, SocketFlags.None); 
      string Nickname = Encoding.ASCII.GetString(MessageBytes); 
      string[] CNickFich = Nickname.Split('$'); 
      FileHandler Handler = new FileHandler(); 
      long DirectorySize = Handler.GetDirectorySize("C:\\" + CNickFich[0]); 
      long FileSize = long.Parse(CNickFich[2]); 
      bool Subs = false; 
      if ((FileSize + DirectorySize) < MaxFolderSize && MaxFileSize > FileSize) 
      { 
       if (!Directory.Exists("C:\\" + CNickFich[0])) 
        Directory.CreateDirectory("C:\\" + CNickFich[0]); 
       if (File.Exists("C:\\" + CNickFich[0] + "\\" + CNickFich[1])) 
       { 
        File.Delete("C:\\" + CNickFich[0] + "\\" + CNickFich[1]); 
        Subs = true; 
       } 
       MessageTypeToBytes MessageInBytes = new MessageTypeToBytes() { TypeOfMessage = MessageType.OK }; 
       ClientSocket.Send(MessageInBytes.MessageBytes, 512, SocketFlags.None); 

       int qtdReceived = 0; 
       long CurrentSize = 0; 
       byte[] FileBuffer = new byte[BufferSize]; 
       FileStream FileStr = new FileStream("C:\\" + CNickFich[0] + "\\" + CNickFich[1], FileMode.CreateNew, FileAccess.Write); 
       BufferedStream BufferStr = new BufferedStream(FileStr); 
       while (CurrentSize < FileSize) 
       { 
        qtdReceived = ClientSocket.Receive(FileBuffer, 0, FileBuffer.Length, 0); 
        CurrentSize += qtdReceived; 
        BufferStr.Write(FileBuffer, 0, qtdReceived); 
        BufferStr.Flush(); 
       } 
       BufferStr.Close(); 
       FileStr.Close(); 
       SqlDataAdapter data = new SqlDataAdapter("SELECT COD_CONTA FROM CONTAS WHERE NICKNAME='" 
       + CNickFich[0] + "'", OConn); 
       DataTable dt = new DataTable(); 
       data.Fill(dt); 
       if (NFicheiro(Handler.MD5HashFromFile("C:\\" + CNickFich[0] + "\\" + CNickFich[1]), "C:\\" + CNickFich[0] + "\\" + CNickFich[1], Subs, 
        int.Parse(dt.Rows[0][0].ToString()), CNickFich[3])) 
        MessageInBytes.TypeOfMessage = MessageType.OK; 
       else 
        MessageInBytes.TypeOfMessage = MessageType.Erro; 
       ClientSocket.Send(MessageInBytes.MessageBytes, 512, SocketFlags.None); 
       //NFicheiro(new FileHandler().MD5HashFromFile("C:\\" + CNickFich[0] + "\\" + CNickFich[1]), "C:\\" + CNickFich[0], false, 1,); 
      } 
      else 
      { 
       MessageTypeToBytes MessageInBytes = new MessageTypeToBytes() { TypeOfMessage = MessageType.Erro }; 
       ClientSocket.Send(MessageInBytes.MessageBytes, 512, SocketFlags.None); 
      } 
     } 
     catch 
     { 
      MessageTypeToBytes MessageInBytes = new MessageTypeToBytes() { TypeOfMessage = MessageType.Erro }; 
      ClientSocket.Send(MessageInBytes.MessageBytes, 512, SocketFlags.None); 
     } 
    } 

客戶:

private void UploadWork_DoWork(object sender, DoWorkEventArgs e) 
    { 
     FileStream FileStr = null; 
     BufferedStream BufferStr = null; 
     Stopwatch Counter = new Stopwatch(); 
     try 
     { 
      int CurrentProgress = 0; 
      Program.CTasks.ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      Program.CTasks.ClientSocket.ReceiveTimeout = 60000; 
      Program.CTasks.ClientSocket.SendTimeout = 60000; 
      Program.CTasks.ClientSocket.Connect(IPAddress.Parse(Program.CTasks.HostName), Program.CTasks.Port); 
      MessageTypeToBytes MessageInBytes = new MessageTypeToBytes() { TypeOfMessage = MessageType.Upload }; 
      Program.CTasks.ClientSocket.Send(MessageInBytes.MessageBytes, 512, SocketFlags.None); 
      FileInfo FileNFO = new FileInfo(Open.FileName); 
      byte[] NickPath = new byte[512]; 
      byte[] UNickPath = Encoding.ASCII.GetBytes(Program.Nickname + "$" + Open.FileName.Substring(Open.FileName.LastIndexOf('\\') + 1) + "$" + FileNFO.Length.ToString() + "$"); 
      byte[] TagCollectionBytes = Encoding.ASCII.GetBytes(TagCollection + "$"); 
      UNickPath.CopyTo(NickPath, 0); 
      TagCollectionBytes.CopyTo(NickPath, UNickPath.Length); 
      Program.CTasks.ClientSocket.Send(NickPath, 512, SocketFlags.None); 
      Program.CTasks.ClientSocket.Receive(MessageInBytes.MessageBytes, 512, SocketFlags.None); 
      if (MessageInBytes.TypeOfMessage == MessageType.OK) 
      { 
       long FileSize = FileNFO.Length; 
       long CurrentFileSize = 0; 
       long qtdRead = 0; 
       byte[] FileBytes = new byte[BufferSizer]; 
       FileStr = new FileStream(Open.FileName, FileMode.Open, FileAccess.Read); 
       BufferStr = new BufferedStream(FileStr); 
       Counter.Start(); 
       while ((qtdRead = BufferStr.Read(FileBytes, 0, FileBytes.Length)) > 0) 
       { 
        Program.CTasks.ClientSocket.Send(FileBytes, 0, FileBytes.Length, 0); 
        CurrentFileSize += qtdRead; 
        CurrentProgress = (int)((CurrentFileSize * 100)/FileSize); 
        UploadSpeed = ((double)CurrentFileSize/(Counter.Elapsed.TotalMilliseconds/100)); 
        UploadWork.ReportProgress(CurrentProgress); 
       } 
       FileStr.Close(); 
       Counter.Stop(); 
       Program.CTasks.ClientSocket.Receive(MessageInBytes.MessageBytes, 512, SocketFlags.None); 
       Program.CTasks.ClientSocket.Close(); 
      } 
     } 
     catch 
     { 
      try 
      { 
       Counter.Stop(); 
       FileStr.Close(); 
       Program.CTasks.ClientSocket.Close(); 
      } 
      catch { } 
     } 
    } 
+0

不介意SQL連接,它只是用來將文件添加到一個帳戶。 – droidsz

回答

2

您發送的數據太多......在文件末尾FileBytes將會更長時間完全填滿,而您應該只發送qtdRead個字節。

更換

Program.CTasks.ClientSocket.Send(FileBytes, 0, FileBytes.Length, 0); 

隨着

Program.CTasks.ClientSocket.Send(FileBytes, 0, qtdRead, 0); 
+0

非常感謝您給我們提供真正快速的答案。我測試了它,它工作正常! – droidsz

1

您在使用緩衝區的長度,而不是發送時您閱讀的內容的長度。

+0

謝謝你,非常好的眼睛! – droidsz