2013-03-11 45 views
0

我已經寫在C#中,從客戶端發送文件到服務器,反之亦然TCP之上的專有協議(客戶端和服務器)。緩慢的下載超過插座

因爲它是在概念全雙工,接收和發送的方法適用於客戶端和服務器一樣。

該協議允許client1將文件上載到server,一旦文件被緩衝(在服務器上),client1可以決定client2和/或client3是否獲得該文件。 (該server可以通過client1唯一發送到client2,只client3,或兩者同時根據請求)。

的問題是,我見證服務器慢的數據傳輸 - >客戶端,約140 KB時的實際帶寬爲在客戶端要高得多,並且顯然對服務器以及/秒。

起初我還以爲它只是爲這個特定的連接(在我的家,服務器在遠程地點的客戶端)的最大帶寬,但後來我看到傳輸速率雙打,當我打開client2client3我PC並讓服務器同時發送它們兩個文件;它對每個客戶端都是一樣的,但由於它們都在同一臺PC上,所以本地網絡的總吞吐​​量翻了一番。

  1. 在哪裏我的問題能有什麼想法?如何將服務器 - >客戶端傳輸速率提高到最大?
  2. 關於我的代碼任何改善的基本點,將不勝感激。

這裏是我的代碼:

struct ReceiveBuffer 
{ 
    public const int BUFFER_SIZE = 1024 * 16; 
    public byte[] BUFFER; 
    public int ToReceive; 
    public MemoryStream BufStream; 

    public ReceiveBuffer(int toRec) 
    { 
     BUFFER = new byte[BUFFER_SIZE]; 
     ToReceive = toRec; 
     BufStream = new MemoryStream(toRec); 
    } 
} 

struct SendBuffer 
{ 
    public const int BUFFER_SIZE = 1024 * 16; 
    public byte[] BUFFER; 
    public int sent; 

    public SendBuffer(byte[] data) 
    { 
     BUFFER = new byte[data.Length]; 
     Buffer.BlockCopy(data, 0, BUFFER, 0, data.Length); 
     sent = 0; 
    } 
} 

public void ReceiveAsync() 
{ 
    try 
    { 
     socket.BeginReceive(lenBuffer, 0, 4, SocketFlags.None, 
          receiveCallback, null);     
    } 
    catch (SocketException se) 
    { 
     //handle disconnection 
    } 

} 

void receiveCallback(IAsyncResult ar) 
{ 
    try 
    { 
     int rec = socket.EndReceive(ar); 
     if (rec == 0) 
     { 
      if (Disconnected != null) 
      { 
       Disconnected(this); 
       return; 
      } 
     } 

     if (rec != 4) 
     { 
      //less than 4 bytes received...error 
      return; 
     } 

     receiveBuffer = new ReceiveBuffer(BitConverter.ToInt32(lenBuffer, 0)); 
     socket.BeginReceive(receiveBuffer.BUFFER, 0, 
          receiveBuffer.BUFFER.Length, 
          SocketFlags.None, receivePacketCallback, null); 
    } 
    catch (SocketException se) 
    { 
     //raise disconnection event 
    } 
} 

void receivePacketCallback(IAsyncResult ar) 
{ 
    try 
    { 
     int rec = socket.EndReceive(ar); 
     if (rec <= 0) 
     { 
      return; 
     } 
     receiveBuffer.BufStream.Write(receiveBuffer.BUFFER, 0, rec); 
     receiveBuffer.ToReceive -= rec; 
     if (receiveBuffer.ToReceive > 0) 
     { 
      Array.Clear(receiveBuffer.BUFFER, 0, receiveBuffer.BUFFER.Length); 
      socket.BeginReceive(receiveBuffer.BUFFER, 0, 
           receiveBuffer.BUFFER.Length, 
           SocketFlags.None, receivePacketCallback, null); 
      return; 
     } 

     if (DataReceived != null) 
     { 
      //raise dataReceived event 
     } 
     receiveBuffer.Dispose(); 
     if (socket !=null) 
      ReceiveAsync(); 

    } 
    catch (SocketException se) 
    { 
     //handle disconnection 
    } 

} 

// Send Async 
public void SendAsyncString(string str, CommandsToClient cmd) 
{ 
    BinaryWriter bw = new BinaryWriter(new MemoryStream()); 
    bw.Write((int)cmd); 
    bw.Write((int)str.Length); 
    bw.Write(Encoding.ASCII.GetBytes(str)); 
    bw.Close(); 
    byte[] data = ((MemoryStream)(bw.BaseStream)).ToArray(); 
    bw.BaseStream.Dispose(); 
    SendAsync(data); 
} 

public void SendAsync(byte[] data) 
{ 
    int toSend; 
    byte[] dataWithHeader = Combine(BitConverter.GetBytes(data.Length), data); 
    sendBuffer = new SendBuffer(dataWithHeader); 
    if (sendBuffer.BUFFER.Length - sendBuffer.sent > SendBuffer.BUFFER_SIZE) 
     toSend = SendBuffer.BUFFER_SIZE; 
    else 
     toSend = sendBuffer.BUFFER.Length - sendBuffer.sent; 
    socket.BeginSend(sendBuffer.BUFFER, 0,toSend, SocketFlags.None, 
        sendCallback, null); 
} 

void sendCallback(IAsyncResult ar) 
{ 
    try 
    { 
     int bytesSent = socket.EndSend(ar); 
     if (bytesSent == 0) 
     { 
      //raise disconnection event 
     } 
     sendBuffer.sent += bytesSent; 
     if (sendBuffer.sent==sendBuffer.BUFFER.Length) 
     { 
      sendBuffer.Dispose(); 
      return; 
     } 
     int toSend; 
     if (sendBuffer.BUFFER.Length - sendBuffer.sent > SendBuffer.BUFFER_SIZE) 
      toSend = SendBuffer.BUFFER_SIZE; 
     else 
      toSend = sendBuffer.BUFFER.Length - sendBuffer.sent; 

     socket.BeginSend(sendBuffer.BUFFER, sendBuffer.sent,toSend, 
         SocketFlags.None, sendCallback, null); 
    } 
    catch (SocketException se) 
    { 
     //hande disconnection 
    } 
} 
+1

是否確定要編寫自己的專有協議?你不能使用現有的東西嗎? – 2013-03-11 07:59:25

+0

@BasileStarynkevitch,是的。我還沒有找到適合我需求的協議。 – Daniel 2013-03-11 08:31:41

+0

所有這些都可以通過幾種現有的協議完成。 – 2013-03-11 08:32:27

回答

0

似乎有什麼正在放緩我失望是緩衝區的大小。

在我的電腦: 我可以上傳@約50千字節/秒
我可以下載@約600千字節/秒 (這些值明顯變化,這取決於在遠程主機上,但是它確實給一個很好的估計)

在服務器上: 上傳和下載更高的帶寬

這裏(兆字節的十位)現在我用這讓我高傳輸速率的設置:

在客戶端(我PC)

Receive Buffer = 128 Kbytes 
Send Buffer = 32 Kbytes 

在服務器端:

Receive Buffer = 64 Kbytes 
Send Buffer = 256 Kbytes