我已經寫在C#中,從客戶端發送文件到服務器,反之亦然TCP之上的專有協議(客戶端和服務器)。緩慢的下載超過插座
因爲它是在概念全雙工,接收和發送的方法適用於客戶端和服務器一樣。
該協議允許client1
將文件上載到server
,一旦文件被緩衝(在服務器上),client1
可以決定client2
和/或client3
是否獲得該文件。 (該server
可以通過client1
唯一發送到client2
,只client3
,或兩者同時根據請求)。
的問題是,我見證服務器慢的數據傳輸 - >客戶端,約140 KB時的實際帶寬爲在客戶端要高得多,並且顯然對服務器以及/秒。
起初我還以爲它只是爲這個特定的連接(在我的家,服務器在遠程地點的客戶端)的最大帶寬,但後來我看到傳輸速率雙打,當我打開client2
和client3
我PC並讓服務器同時發送它們兩個文件;它對每個客戶端都是一樣的,但由於它們都在同一臺PC上,所以本地網絡的總吞吐量翻了一番。
- 在哪裏我的問題能有什麼想法?如何將服務器 - >客戶端傳輸速率提高到最大?
- 關於我的代碼任何改善的基本點,將不勝感激。
這裏是我的代碼:
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
}
}
是否確定要編寫自己的專有協議?你不能使用現有的東西嗎? – 2013-03-11 07:59:25
@BasileStarynkevitch,是的。我還沒有找到適合我需求的協議。 – Daniel 2013-03-11 08:31:41
所有這些都可以通過幾種現有的協議完成。 – 2013-03-11 08:32:27