簡體   English   中英

使用套接字接收數據包

[英]Receiving Packet using Socket

我是Socket編程的新手,我只想問些什么。

我試圖在客戶端和服務器之間創建Simple Receiver和Sender數據包(嗯,我使用的是同一台計算機),但是我遇到了問題...

發送功能正常運行,但是我不知道如何接收與發送的數據包大小完全相同的數據包。

例如,我從客戶端向服務器發送5個字節,我只想讓服務器也只接收5個字節,不多也不少,我想用Socket來做到這一點,我也已經包括了短數據包的大小(int16 2字節)格式。 這是我的發送數據包代碼:

    public static void Send(Socket socket, byte[] buffer, int timeout)
    {
        int startTickCount = Environment.TickCount;
        int sent = 0;
        int offset = 0;
        int size = buffer.Length;

        // Add size of packet in the begin of data packet with short (int16) format
        List<byte> tmpdata = new List<byte>();
        tmpdata.AddRange(BitConverter.GetBytes((short)(buffer.Length + 2)));
        tmpdata.AddRange(buffer);
        buffer = tmpdata.ToArray();

        do
        {
            if (Environment.TickCount > startTickCount + timeout)
                throw new Exception("Sending packet was timeout.");
            try
            {
                sent += socket.Send(buffer, offset + sent, size - sent, SocketFlags.None);
            }
            catch (SocketException ex)
            {
                if (ex.SocketErrorCode == SocketError.WouldBlock ||
                    ex.SocketErrorCode == SocketError.IOPending ||
                    ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
                {
                    Thread.Sleep(30);
                }
                else
                    throw ex;
            }
        } while (sent < size);
    }

有人能幫我嗎?


感謝Damien的修復並且找到了解決方案,但由於循環每個字節,因此恐怕這會占用內存,下面是代碼:

    public static byte[] Receive(Socket socket)
    {
        System.Net.Sockets.NetworkStream ns = new NetworkStream(socket);
        int b = (byte)1;
        List<byte> databuf = new List<byte>();

        while ((b = ns.ReadByte()) != -1)
            databuf.Add((byte)b);

        return databuf.ToArray();
    }

沒有NetworkStream,有沒有更好的解決方案,或者還有更好的性能? 謝謝

您尚未顯示接收代碼,但可以輕松修復一個錯誤:

    // Add size of packet in the begin of data packet with short (int16) format
    List<byte> tmpdata = new List<byte>();
    tmpdata.AddRange(BitConverter.GetBytes((short)(buffer.Length + 2)));
    tmpdata.AddRange(buffer);
    buffer = tmpdata.ToArray();
    int size = buffer.Length; //Moved from higher up, now that buffer is a different size

在接收端,您應該有類似的代碼-循環直到您讀取2個字節,使用它來創建一個short ,即要接收的總大小,減去2(老實說,我只是避免在上面的代碼中加2並以忽略大小編碼的實際字節的大小發送該大小),然后再次循環直到您閱讀了整個消息。

沒有NetworkStream,有沒有更好的解決方案,或者還有更好的性能?

NetworkStream充當Socket的高級包裝,因此您可以直接使用它做同樣的事情:

var targetStream = new MemoryStream();
var buffer = new byte[receiveBufferSize];
int bytesReceived = 0;

while ((bytesReceived = socket.Receive(buffer)) > 0)
{
    targetStream.Write(buffer, 0, bytesReceived);
}

當需要執行多個並發操作時, Socket中還有SendAsyncReceiveAsync方法可以很好地工作。 但是它們更加復雜:

var receive = new SocketAsyncEventArgs();
var receiveBuffer = new byte[receiveBufferSize];
receive.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
receive.Completed += HandleReceived;

if (!socket.ReceiveAsync(receive))
{
    HandleReceived(this, receive);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM