Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 服务器没有';无法从列表中删除客户端_C#_Sockets_Client Server_Listener - Fatal编程技术网

C# 服务器没有';无法从列表中删除客户端

C# 服务器没有';无法从列表中删除客户端,c#,sockets,client-server,listener,C#,Sockets,Client Server,Listener,我有一个客户端服务器应用程序。 服务器可以处理多个客户端连接 当我在客户端中单击Close按钮时,我希望它会断开连接,并从服务器表单中的客户端列表中删除 但是,它进入一个无限循环,这会导致客户机从表单的列表视图中删除,然后再次添加到表单的列表视图中 这是我的密码: RemoteBatcherClient表单: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data

我有一个客户端服务器应用程序。
服务器可以处理多个客户端连接

当我在客户端中单击
Close
按钮时,我希望它会断开连接,并从服务器表单中的客户端列表中删除

但是,它进入一个无限循环,这会导致客户机从表单的
列表视图中删除,然后再次添加到表单的
列表视图中

这是我的密码:

RemoteBatcherClient表单

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace RemoteBatcherClient
{
    public partial class RemoteBatcherClientForm : Form
    {
        Socket clientSock;

        public RemoteBatcherClientForm()
        {
            InitializeComponent();
            clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        private void connectBtn_Click(object sender, EventArgs e)
        {
            clientSock.Connect("127.0.0.1", 8);
            MessageBox.Show("Connected");
        }

        private void sendBtn_Click(object sender, EventArgs e)
        {
            if (clientSock.Send(Encoding.Default.GetBytes(txtMsg.Text)) > 0)
            {
                MessageBox.Show("Data Sent");
            }
        }

        private void closeBtn_Click(object sender, EventArgs e)
        {
            clientSock.Close();
            clientSock.Dispose();
            Close();
        }
    }
}
RemoteBatcherServer

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace RemoteBatcherClient
{
    public partial class RemoteBatcherClientForm : Form
    {
        Socket clientSock;

        public RemoteBatcherClientForm()
        {
            InitializeComponent();
            clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        private void connectBtn_Click(object sender, EventArgs e)
        {
            clientSock.Connect("127.0.0.1", 8);
            MessageBox.Show("Connected");
        }

        private void sendBtn_Click(object sender, EventArgs e)
        {
            if (clientSock.Send(Encoding.Default.GetBytes(txtMsg.Text)) > 0)
            {
                MessageBox.Show("Data Sent");
            }
        }

        private void closeBtn_Click(object sender, EventArgs e)
        {
            clientSock.Close();
            clientSock.Dispose();
            Close();
        }
    }
}
Client.cs:

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

namespace RemoteBatcherServer
{
    class Client
    {
        public string ID
        {
            get;
            private set;
        }

        public IPEndPoint EndPoint
        {
            get;
            private set;
        }

        Socket serverSock;

        public Client(Socket accepted)
        {
            serverSock = accepted;

            ID = Guid.NewGuid().ToString();
            EndPoint = (IPEndPoint)serverSock.RemoteEndPoint;
            serverSock.BeginReceive(new byte[] { 0 }, 0, 0, 0, callback, null);
        }

        void callback(IAsyncResult ar)
        {
            try
            {
                serverSock.EndReceive(ar);

                byte[] receiveBuffer = new byte[8192];

                int rec = serverSock.Receive(receiveBuffer, receiveBuffer.Length, 0);

                if (rec < receiveBuffer.Length)
                {
                    Array.Resize<byte>(ref receiveBuffer, rec);
                }

                 if (Receieved != null)
                {
                    Receieved(this, receiveBuffer);
                }

                serverSock.BeginReceive(new byte [] {0}, 0, 0, 0, callback, null);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
                Close();

                if (Disconnected != null)
                {
                    Disconnected(this);
                }
            }
        }

        public void Close()
        {
            serverSock.Close();
            serverSock.Dispose();
        }

        public delegate void ClientReceievedHandler(Client sender, byte[] data);
        public delegate void ClientDisconnectedHandler(Client sender);

        public event ClientReceievedHandler Receieved;
        public event ClientDisconnectedHandler Disconnected;
    }
}
RemoteBatcherServerForm.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace RemoteBatcherServer
{
    public partial class RemoteBatcherServerForm : Form
    {
        Listener listener;

        public RemoteBatcherServerForm()
        {
            InitializeComponent();
            listener = new Listener(8);
            listener.SockeetAccepted += new Listener.SocketAcceptHandler(listenerSocketAccepted);

            Load += new EventHandler(MainLoad);
        }

        void MainLoad(object sender, EventArgs e)
        {
            listener.Start();
        }

        void listenerSocketAccepted(Socket socket)
        {
            Client client = new Client(socket);
            client.Receieved += new Client.ClientReceievedHandler(clientReceived);
            client.Disconnected += new Client.ClientDisconnectedHandler(clientDisconnected);

            Invoke((MethodInvoker)delegate
            {
                ListViewItem item = new ListViewItem();
                item.Text = client.EndPoint.ToString();
                item.SubItems.Add(client.ID);
                item.SubItems.Add("XX");
                item.SubItems.Add("XX");
                item.Tag = client;
                lstClients.Items.Add(item);
            });
        }

        void clientReceived(Client sender, byte[] data)
        {
            Invoke((MethodInvoker)delegate
            {
                for (int i = 0; i < lstClients.Items.Count; i++)
                {
                    Client client = lstClients.Items[i].Tag as Client;

                    if (client.ID == sender.ID)
                    {
                        lstClients.Items[i].SubItems[2].Text = Encoding.Default.GetString(data);
                        lstClients.Items[i].SubItems[3].Text = DateTime.Now.ToString();
                        break;
                    }
                }
            });
        }

        void clientDisconnected(Client sender)
        {
            Invoke((MethodInvoker)delegate
            {
                for (int i = 0; i < lstClients.Items.Count; i++)
                {
                    Client client = lstClients.Items[i].Tag as Client;

                    if (client.ID == sender.ID)
                    {
                        lstClients.Items.RemoveAt(i);
                        break;
                    }
                }
            });
        }       
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
Net系统;
使用System.Net.Sockets;
命名空间RemoteBatcherServer
{
公共部分类RemoteBatcherServerForm:Form
{
倾听者;
公共RemoteBatcherServerForm()
{
初始化组件();
侦听器=新侦听器(8);
listener.SockeetAccepted+=新的listener.SocketAcceptHandler(listenerSocketAccepted);
Load+=新事件处理程序(MainLoad);
}
void MainLoad(对象发送器、事件参数)
{
listener.Start();
}
无效listenerSocketAccepted(套接字)
{
客户端=新客户端(套接字);
client.received+=新client.clientreceivedHandler(clientReceived);
client.Disconnected+=new client.ClientDisconnectedHandler(clientDisconnected);
调用((MethodInvoker)委托
{
ListViewItem=新建ListViewItem();
item.Text=client.EndPoint.ToString();
item.SubItems.Add(client.ID);
项目.子项目.添加(“XX”);
项目.子项目.添加(“XX”);
item.Tag=客户端;
lstClients.Items.Add(item);
});
}
void clientReceived(客户端发送方,字节[]数据)
{
调用((MethodInvoker)委托
{
对于(int i=0;i

有什么想法吗?

除非我误解了你的代码,否则你似乎在混合同步和异步调用。我想你正在用你的serverSock无限期地阻塞。接听电话。请参阅:-“如果没有可读取的数据,则接收方法将阻塞,直到数据可用为止,除非使用Socket.ReceiveTimeout设置了超时值”

尝试检查是否已收到0字节。您可能还希望将receive调用替换为BeginReceive。这可能看起来有点混乱,因为您实际上希望继续重新调用BeginReceive,直到收到0字节,这表明另一端已关闭连接:

int i = serverSock.EndReceive(ar);
if (i > 0)
    {
        serverSock.BeginReceive(receiveBuffer, 0, receiveBuffer.Length, 0, 
                                 new AsyncCallback(callback), null);
    }
else
    {
        serverSock.Close();
    }

注意,您可以将null参数交换为传递的状态对象。您可以在客户端构造函数中的初始BeginReceive调用中执行此操作-这可能是传递缓冲区的更好方法,用某种状态类包装它。

这里有一个快速答案:修改
Client.cs
无效回调(IAsyncResult ar)
方法以检查是否返回0(当客户端关闭时发生此情况):

void回调(IAsyncResult ar)
{
尝试
{
//添加这些行
if(serverSock.Available==0)
{
断开(这个);
返回;
}
serverSock.EndReceive(ar);
字节[]接收缓冲区=新字节[8192];
int rec=serverSock.Receive(receiveBuffer,receiveBuffer.Length,0);
if(rec
不会帮助您,但您在
Listener.cs
-
SockeeTacepted
中有一个输入错误。应
SocketAccepted
。谢谢,我已修复了输入错误。
int i = serverSock.EndReceive(ar);
if (i > 0)
    {
        serverSock.BeginReceive(receiveBuffer, 0, receiveBuffer.Length, 0, 
                                 new AsyncCallback(callback), null);
    }
else
    {
        serverSock.Close();
    }
void callback(IAsyncResult ar)
{
    try
    {
        //add these lines
        if (serverSock.Available == 0)
        {
            Disconnected(this);
            return;
        }

        serverSock.EndReceive(ar);

        byte[] receiveBuffer = new byte[8192];

        int rec = serverSock.Receive(receiveBuffer, receiveBuffer.Length, 0);

        if (rec < receiveBuffer.Length)
        {
            Array.Resize<byte>(ref receiveBuffer, rec);
        }

        if (Receieved != null)
        {
            Receieved(this, receiveBuffer);
        }

        serverSock.BeginReceive(new byte[] { 0 }, 0, 0, 0, callback, null);
    }
    catch (System.Exception ex)
    {
        Console.WriteLine(ex.Message);
        Close();

        if (Disconnected != null)
        {
            Disconnected(this);
        }
    }
}