C# - 异步套接字获取错误的字节[] 长度

本文关键字:字节 长度 取错误 异步 套接字 获取 | 更新日期: 2023-09-27 18:17:47

你好社区,我遇到了一个大问题。我想使用 C# 创建一个客户端 - 服务器应用程序。

但是,如果我将数据作为 byte[] 发送到我的客户端,他会随着服务器发送而获得更多字节。

如果我使用字符串 x = 编码.UTF8.GetString(bytesFromServer(;此字符串中的信息比我的服务器上的信息少。

我真的很困惑。我希望你能帮助我。

服务器代码:

public class Server
{
    private static object serverLock = new object();
    private static int port = 5177;
    private static Socket serverSocket;
    private class ConnectionInfo
    {
        public string deviceName;
        public Socket Socket;
        public byte[] Buffer;
    }
    private static List<ConnectionInfo> connections = new List<ConnectionInfo>();
    public static void Start()
    {
        try
        {
            createAndStartSocket();
            for (int i = 0; i < 10; i++)
            {
                serverSocket.BeginAccept(new AsyncCallback(acceptCallback), serverSocket);
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine("Error: ");
            Debug.WriteLine(e.ToString());
        }
    }
    public static void Stop()
    {
        try
        {
            serverSocket.Close();
        }
        catch
        {
            Debug.WriteLine("Error while Closing Socket!");
        }
    }
    private static void createAndStartSocket()
    {
        IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Any, port);
        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        serverSocket.Blocking = false;
        serverSocket.Bind(myEndpoint);
        serverSocket.Listen((int)SocketOptionName.MaxConnections); ;
    }
    private static void acceptCallback(IAsyncResult result)
    {
        ConnectionInfo connection = new ConnectionInfo();
        try
        {
            Socket s = (Socket)result.AsyncState;
            connection.Socket = s.EndAccept(result);
            connection.Socket.Blocking = false;
            connection.Buffer = new byte[1024];
            lock (connections)
            {
                connections.Add(connection);
            }
            Debug.WriteLine("New connection from " + s);
            // Start Receive
            connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.Partial, new AsyncCallback(receiveCallback), connection);
            serverSocket.BeginAccept(new AsyncCallback(acceptCallback), result.AsyncState);
        }
        catch (Exception e)
        {
            closeConnection(connection);
            Debug.WriteLine("Exception: ");
            Debug.WriteLine(e.ToString());
        }
    }
    private static void closeConnection(ConnectionInfo connection)
    {
        connection.Socket.Close();
        lock (connections)
        {
            connections.Remove(connection);
        }
    }
    private static void receiveCallback(IAsyncResult result)
    {
        ConnectionInfo connection = (ConnectionInfo)result.AsyncState;
        try
        {
            int bytesRead = connection.Socket.EndReceive(result);
            if (0 != bytesRead)
            {
                string command = String.Empty;
                command = UTF8Encoding.UTF8.GetString(connection.Buffer);
                byte[] answer = DataController.GetData(command);
                lock (connections)
                {
                    foreach (ConnectionInfo conn in connections)
                    {
                        if (connection == conn)
                        {
                            conn.Socket.Send(answer, answer.Length,
                                SocketFlags.Partial);
                        }
                    }
                }
                connection.Socket.BeginReceive(connection.Buffer, 0,
                    connection.Buffer.Length, SocketFlags.Partial,
                    new AsyncCallback(receiveCallback), connection);
            }
        }
        catch
        {
            closeConnection(connection);
        }
    }
}

和客户:

public class SocketInfo
{
    public byte[] Buffer = new byte[1024];
    public Socket Socket = null;
    public List<byte> byteList = new List<byte>();
}
public class Connection
{
    private string _address;
    private int _port;
    private IPEndPoint _clientEndpoint;
    private List<SocketInfo> socketList = new List<SocketInfo>();

    public bool Start(string address, int port)
    {
        _address = address;
        _port = port;
        IPAddress add = IPAddress.Parse(_address);
        _clientEndpoint = new IPEndPoint(add, _port);
        _address = _clientEndpoint.Serialize().ToString();
        Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        SocketInfo info = new SocketInfo();
        info.Socket = clientSocket;
        lock (socketList)
        {
            socketList.Add(info);
        }
        Debug.Write("Connecting... ");
        try
        {
            info.Socket.Connect(_clientEndpoint);
            Debug.WriteLine("Done.");
            info.Socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), info);
            return true;
        }
        catch (Exception e)
        {
            lock (socketList)
            {
                socketList.Remove(info);
            }
            Debug.WriteLine("Fail.");
            Debug.WriteLine(e);
            return false;
        }
    }
    public bool SendRequestToServer(string[] command)
    {
        try
        {
            switch (command[0])
            {
                case "service":
                    Thread th = new Thread(new ThreadStart(ServicesThread));
                    th.Start();
                    break;
                default:
                    break;
            }
            return true;
        }
        catch
        {
            return false;
        }
    }
    private void ServicesThread()
    {
        try
        {
            byte[] request = Encoding.UTF8.GetBytes("runningservices");
            lock (socketList)
            {
                foreach (SocketInfo si in socketList)
                {
                    si.Socket.Send(request, request.Length,
                        SocketFlags.None);
                    Debug.WriteLine("serviceRequest sendet!");
                    si.Socket.BeginReceive(si.Buffer, 0,
                        si.Buffer.Length, SocketFlags.None,
                        new AsyncCallback(receiveCallback), si);
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Unable to send data. Connection lost.");
        }
        Thread.Sleep(10);
        Debug.WriteLine("Services thread stopped.");
    }
    private void receiveCallback(IAsyncResult result)
    {
        SocketInfo info = (SocketInfo)result.AsyncState;
        try
        {
            int bytesToRead = info.Socket.EndReceive(result);
            if (bytesToRead > 0)
            {
                info.byteList.AddRange(info.Buffer);
                //  Get the rest of the data.
                if (bytesToRead == info.Buffer.Length)
                {
                    info.Socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, 0,
                        new AsyncCallback(receiveCallback), info);
                }
                else
                {
                    if (info.byteList.Count > 0)
                    {
                        byte[] completeMessage = info.byteList.ToArray();
                        string incommingResult = Encoding.UTF8.GetString(completeMessage);
                        info.byteList.Clear();
                        //Following Code
                        info.Socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, 0,
                        new AsyncCallback(receiveCallback), info);
                    }
                }
            }
            else
            {
                if (info.byteList.Count > 0)
                {
                    byte[] completeMessage = info.byteList.ToArray();                        
                    string incommingResult = Encoding.UTF8.GetString(completeMessage);
                    info.byteList.Clear();
                    //Following Code
                }
            }
        }
        catch (Exception e)
        {
            lock (socketList)
            {
                socketList.Remove(info);
            }
            Debug.WriteLine("Client Disconnected.");
            Debug.WriteLine(e);
        }
    }
}

就我而言,服务器说"答案。长度" = 9895客户端说"completeMessage.Length" = 9945。

我希望你能帮助我。谢谢!

C# - 异步套接字获取错误的字节[] 长度

您始终在此处添加缓冲区的全部内容:

info.byteList.AddRange(info.Buffer);

只需添加使用的缓冲区部分:

info.byteList.AddRange(info.Buffer.Take(bytesToRead));