0

我在 C# 的 TCP 之上编写了一个专有协议(客户端和服务器),它将文件从客户端发送到服务器,反之亦然。

由于它在概念上是全双工的,因此客户端和服务器的接收和发送方法是相同的。

该协议允许client1将文件上传到server,并且一旦文件被缓冲(在服务器上),client1就可以决定是否client2和/或client3获取文件。(根据 的请求,可以同时server将唯一发送到client2、仅发送到或同时发送到两者)。client3client1

问题是我看到服务器 -> 客户端的数据传输速度很慢,大约 140 kb/s,而客户端的实际带宽要高得多,显然服务器也是如此。

起初我以为这只是这个特定连接的最大带宽(我家的客户端和远程位置的服务器),但后来我发现当我打开并在我的 PC 上让服务器发送它们时传输速率翻倍文件同时;每个客户端都保持不变,但由于它们都在同一台 PC 上,我的本地网络上的总吞吐量翻了一番。client2client3

  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
    }
}
4

1 回答 1

0

似乎让我慢下来的是缓冲区大小。

在我的 PC 上:我可以上传 @ 大约 50 KB/秒
我可以下载 @ 大约 600 KB/秒(这些值显然会发生变化,具体取决于远程主机,但它确实给出了一个很好的估计)

在服务器上:上传和下载更高的带宽(数十兆字节)

这是我现在使用的设置,可以让我获得高传输率:

在客户端(我的电脑)

Receive Buffer = 128 Kbytes
Send    Buffer = 32  Kbytes

在服务器端:

Receive Buffer =  64 Kbytes
Send    Buffer =  256 Kbytes
于 2013-03-11T16:59:30.277 回答