如何在ListViewItem中操作多个套接字?

时间:2018-11-06 03:06:39

标签: c# sockets listview visual-studio-2013

我分别在服务器和客户端(客户端连接到服务器)上有2个套接字,在服务器上我有一个类,其中包含每个客户端的一些信息,例如 IP Socket ID

对于每个接受的连接,我添加连接到该List的最后一个客户端,这样,我就获得了一个客户端列表(即一个对象)。并且还将每个客户端添加到一个ListView中,并在ListViewItem Tag 属性中为该客户端分配了对象引用。如果您想向特定客户端发送消息,这是以后可以提供帮助的一种方法。

就像您可以看到,List个客户端仅引用1个侦听确定端口号的套接字。现在我已经在服务器(客户端)和服务器(客户端)两边各有2个套接字,如果我想从服务器的第二个Socket向客户端的第二个Socket发送消息,我该如何做?例如,是否可以将多个对象分配给ListViewItem Tag 属性(仅是一个主意)?

下面是我的代码(服务器,仅与1个Socket和1个对象(客户端的List)兼容):

表格:

namespace mainForm
{

public partial class frmMain : Form
{
Listener server;
Thread start;

public frmMain()
{
    InitializeComponent();
    server = new Listener();
}

private void startToolStripMenuItem_Click(object sender, EventArgs e)
{
    start = new Thread(listen);
    start.Start();
}

private void listen()
{
    server.BeginListen(101); // Select a port to listen
    server.Received += new Listener.ReceivedEventHandler(server_Received);
    server.Disconnected += new Listener.DisconnectedEventHandler(server_Disconnected);
}

private void server_Disconnected(Listener l, Info i)
{
    Invoke(new _Remove(Remove), i);
}

private void server_Received(Listener l, Info i, string received)
{

    string[] cmd = received.Split('|');
    int inc;

    for (inc = 0; inc < cmd.Length; inc++)
    {

        switch (cmd[inc].ToString())
        {
            case "CMD1":

                Invoke(new _Add(Add), i, cmd[2] + " - " + cmd[3]);

                break;

            case "CMD2":

                 // Other code here

                break;

        }
    }
}

private delegate void _Add(Info i, string computer);
    private void Add(Info i, string computer)
    {
        string[] splitIP = i.RemoteAddress.Split(':');

        ListViewItem item = new ListViewItem();
        item.Text = i.ID.ToString();
        item.SubItems.Add(splitIP[0]);
        item.SubItems.Add(computer);
        item.Tag = i;

        lvConnections.Items.Add(item);

    }

private delegate void _Remove(Info i);
    private void Remove(Info i)
    {
        foreach (ListViewItem item in lvConnections.Items)
        {
            if ((Info)item.Tag == i)
            {
                item.Remove();
                break;
            }
        }
    }

private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
{
    foreach (ListViewItem item in lvConnections.SelectedItems)
    {
        Info client = (Info)item.Tag;
        client.Send("DISCONNECT" + Environment.NewLine);
    }
}

监听器:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;

class Listener
{
    Socket s;
    public List<Info> clients;

    public delegate void ReceivedEventHandler(Listener l, Info i, string received);
    public event ReceivedEventHandler Received;
    public delegate void DisconnectedEventHandler(Listener l, Info i);
    public event DisconnectedEventHandler Disconnected;

    bool listening = false;

    public Listener()
    {
        clients = new List<Info>();
        s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    }

    public bool Running
    {
        get { return listening; }
    }

    public void BeginListen(int port)
    {
        s.Bind(new IPEndPoint(IPAddress.Any, port));
        s.Listen(100);
        s.BeginAccept(new AsyncCallback(AcceptCallback), s);
        listening = true;
    }

    public void StopListen()
    {
        if (listening == true)
        {
            s.Close();
            listening = false;
        }
    }

    void AcceptCallback(IAsyncResult ar)
    {
        Socket handler = (Socket)ar.AsyncState;
        Socket sock = handler.EndAccept(ar);
        Info i = new Info(sock);
        clients.Add(i);

        sock.BeginReceive(i.buffer, 0, i.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), i);
        handler.BeginAccept(new AsyncCallback(AcceptCallback), handler);
    }

    void ReadCallback(IAsyncResult ar)
    {
        Info i = (Info)ar.AsyncState;
        try
        {
            int rec = i.sock.EndReceive(ar);
            if (rec != 0)
            {
                string data = Encoding.UTF8.GetString(i.buffer, 0, rec);
                Received(this, i, data);
            }
            else
            {
                Disconnected(this, i);
                return;
            }

            i.sock.BeginReceive(i.buffer, 0, i.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), i);
        }
        catch (Exception ex)
        {
            Disconnected(this, i);
            i.sock.Close();
            clients.Remove(i);
        }
    }
}

信息:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class Info
{
    public Socket sock;
    public Guid ID;
    public string RemoteAddress;
    public byte[] buffer = new byte[8192];

    public Info(Socket sock)
    {
        this.sock = sock; 
        ID = Guid.NewGuid(); 
        RemoteAddress = sock.RemoteEndPoint.ToString(); 
    }

    public void Send(string data)
    {
        byte[] buffer = Encoding.UTF8.GetBytes(data);
        sock.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback((ar) =>
        {
            sock.EndSend(ar);
        }), buffer);
    }
}

EDITION:

这是上面的代码已经使=>

enter image description here

这就像我想要的一样(也可以在选定的客户端中与 Socket 02 一起使用)=>

enter image description here

0 个答案:

没有答案