ListViewItem 标记 属性 可以包含 Socket 对象吗

Can a ListViewItem Tag property contain a Socket object

在我的服务器端,我设置了一个单线程代码,每次客户端连接时都会创建一个新的 Socket 对象。然后我将我从客户端获得的任何数据连同连接到数据包处理程序的套接字一起传递,并在那里进行计算。在我的主窗体中,我有一个通过 entity framework 填充的列表视图,每当来自已注册计算机的数据包连接时,我都会更新列表视图。所以我的问题是,当我更新它时,我可以从数据包处理程序 class 将套接字对象传递给列表视图的标签 属性 吗?

我的服务器端代码:

private void ReceivedCallback(IAsyncResult result)
    {
        Socket clientSocket = result.AsyncState as Socket;
        SocketError ER;
        try
        {
            int bufferSize = clientSocket.EndReceive(result, out ER);
            if (ER == SocketError.Success)
            {
                byte[] packet = new byte[bufferSize];
                Array.Copy(_buffer, packet, packet.Length);
                Console.WriteLine("Handling packet from IP:" + clientSocket.RemoteEndPoint.ToString());
                //Handle packet stuff here.
                PacketHandler.Handle(packet, clientSocket);
                _buffer = new byte[61144];
                clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, clientSocket);
                //clientSocket.BeginReceive(new byte[] { 0 }, 0, 0, 0, ReceivedCallback, clientSocket);
            }
            else
            {
                Console.WriteLine("No bytes received, we're closing the connection.");
                clientSocket.Close();
            }
        }catch(SocketException ex)
        {
            Console.WriteLine("We caught a socket exception:" + ex.Message);
            clientSocket.Close();
        }
    }

还有我的数据包处理程序class:

public static void Handle(byte[] packet, Socket clientSocket)
    {
        if (clientSocket.Connected)
        {
            if (packet.Length > 0)
            {
                IPEndPoint RemoteIP = (IPEndPoint)clientSocket.RemoteEndPoint;
                ushort packetLength = BitConverter.ToUInt16(packet, 0);
                ushort packetType = BitConverter.ToUInt16(packet, 2);
                ushort packetID = BitConverter.ToUInt16(packet, 4);
                Console.WriteLine("We received a packet of Type: {0}, ID: {1} FROM {2}", packetType, packetID, RemoteIP.ToString());

                if (packetType == 1)
                {
                    switch (packetID)
                    {
                        case 1://Check if computer is registered in the database
                            CheckRegisteredRequest request1 = new CheckRegisteredRequest(packet);
                            Console.WriteLine("We received (Case 1): " + request1.Text);
                            string Response = "";
                            bool found = false;
                            ServerDbContext database = new ServerDbContext();
                            foreach (computers pcs in database.computers)
                            {
                                if (pcs.name == request1.Text.Split(',')[0])
                                {
                                    found = true;
                                    if (pcs.computer_ip == request1.Text.Split(',')[1])
                                    {
                                        //We found a computer with that name and ip address
                                        Response = "true";
                                        CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
                                        clientSocket.Send(resp1.Data);
                                        computers registeredPC;
                                        var name = request1.Text.Split(',')[0];
                                        using (var ctx = new ServerDbContext())
                                        {
                                            registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
                                        }
                                        if (registeredPC != null)
                                        {
                                            registeredPC.networkStatus = "online";
                                        }
                                        using (var ctx = new ServerDbContext())
                                        {
                                            ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
                                            ctx.SaveChanges();
                                        }
                                        addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
                                        RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
                                        break;
                                    }
                                    else
                                    {
                                        //We found a computer with that name but a different ip address, update it
                                        var name = request1.Text.Split(',')[0];
                                        var registeredPC = new computers();
                                        using (var ctx = new ServerDbContext())
                                        {
                                            registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
                                        }
                                        if (registeredPC != null)
                                        {
                                            var ip = request1.Text.Split(',')[1];
                                            registeredPC.computer_ip = ip;
                                            registeredPC.networkStatus = "online";
                                        }

                                        using (var ctx = new ServerDbContext())
                                        {
                                            ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
                                            ctx.SaveChanges();
                                        }
                                        Response = "true";
                                        CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
                                        clientSocket.Send(resp1.Data);
                                        addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
                                        RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
                                        break;
                                    }
                                }
                            }
                            if (!found)
                            {
                                //There is no computer with that name in the database so send false
                                Response = "false";
                                CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
                                clientSocket.Send(resp1.Data);
                            }
                            break;... and so on....

所以我尝试通过处理程序:

这是我的自定义事件处理程序参数:

public class TextArgs : EventArgs
{
    #region Fields
    private string szMessage;
    private Socket _sockets123;
    #endregion Fields

    #region ConstructorsH
    public TextArgs(string TextMessage,Socket sock)
    {
        if (sock != null)
        {
            _sockets123 = sock;
            szMessage = TextMessage;
        }
        else
        {
            szMessage = TextMessage;
        }
    }
    #endregion Constructors

    #region Properties
    public string Message
    {
        get { return szMessage; }
        set { szMessage = value; }
    }

    public Socket _socket
    {
        get { return _sockets123; }
        set { _sockets123 = value; }
    }
    #endregion Properties
}

这就是我在 PacketHandler class 中定义处理程序的方式: public 静态事件 LogsEventHandler 反馈;

    private static void RaiseFeedback(string p, Socket sock)
    {
        LogsEventHandler handler = Feedback;
        if (handler != null)
        {
            handler(null,new TextArgs(p,sock));
        }
    }

每当计算机注册或连接时,我都会执行以下操作:

RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], clientSocket); 

RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], null);

并且在我的主窗体中这两个方法的事件触发:

        private void OnFeedbackReceived(object sender, TextArgs e)
    {
        Invoke((MethodInvoker)delegate
            {
                UpdateComputers();
                UpdateGUI(e.Message,e._socket);
            }
        );            
    }

    public void UpdateGUI(string s, Socket sock)
    {
        LogBox.Text += s;
        LogBox.AppendText(Environment.NewLine);
        using (var context = new ServerDbContext())
        {
            var PCInfo = context.viewUsersInfo;
            dataGridView1.DataSource = PCInfo.ToList();
        }
        if (sock != null)
        {
            ListViewItem item = ComputersList.FindItemWithText(s.Split(':')[1].ToString());
            item.Tag = sock;
        }
    }

问题:是的,你可以。 Control.Tag 是对象类型,几乎可以容纳您选择的任何东西。

所以你可以这样写

Socket socket = someSocket;
ListViewItem item = listView1.FindItemWithText(someText);
if (item != null) item.Tag = socket; else Console.WriteLine(someText + " not found!);

并将其检索为:

if (item.Tag != null) someSocket = item.Tag AS socket;
if (someSocket  != null) ..

取回时注意演员表是否成功,以及 Socket 是否还健在..

问题:您代码中的 Whosebug 是由于一个错误 short-circuited 属性,您现在已经修复了。一般来说,你只需要写显式 getter 和 setter,如果它们实际上做的不仅仅是获取和设置。

他们可以注销测试数据、更新其他依赖属性、进行检查或转换或做其他事情。

但如果需要 none,只需不要创建私有字段并编写自动 getter 和设置器:

public Socket MySocket {get; set;}

另请注意 naming convention asks you to capitalize 属性名称!