当前位置:编程学习 > C#/ASP.NET >>

求教一个关于Socket断开的问题

这是个简易的多人聊天室后台。


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.Threading;
using System.Net;
using System.Net.Sockets;

namespace Server
{
    public partial class Form1 : Form
    {
        delegate void ListBoxAddItemDelegate(String s);
        ListBoxAddItemDelegate listBoxAddItemDelegate;

        private IPEndPoint serverEndPoint;
        private Socket socket;
        private List<Socket> clientSockets;
        private Thread listen;
        private byte[] buffer;

        public Form1()
        {
            InitializeComponent();
            listBoxAddItemDelegate = new ListBoxAddItemDelegate(listBoxAddItem);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            buffer=new byte[65535];
            clientSockets = new List<Socket>();
            listen=new Thread(listenClient);

            IPHostEntry local = Dns.GetHostByName(Dns.GetHostName());
            MessageBox.Show(local.AddressList[0].ToString());
            serverEndPoint = new IPEndPoint(local.AddressList[0], 21368);
            
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(serverEndPoint);
            socket.Listen(10);

            listen.Start();
        }

        private void listenClient()
        {
            while (true)
            {
                clientSockets.Add(socket.Accept());
                Socket aClient=clientSockets.Last();
                aClient.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(catchClient), aClient);
                clientListBox.Invoke(listBoxAddItemDelegate, aClient.RemoteEndPoint.ToString()+"  现人数:"+ clientSockets.Count);
            }
        }

        private void catchClient(IAsyncResult ar)
        {
                Socket client = (Socket)ar.AsyncState;
                int read = client.EndReceive(ar);
                boardCast(buffer, read);
                try
                {
                    client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(catchClient), client);
                }
                catch
                {

                }
        }

        private void boardCast(byte[] buffer,int size)
        {
            
            foreach (Socket myClient in clientSockets)
            {
                try
                {
                    if (myClient.Connected)
                    {
                        myClient.Send(buffer, 0, size, SocketFlags.None);
                    }

                }
                catch
                {
                    listBoxAddItem("Lost a Client! IP:" + myClient.RemoteEndPoint.ToString());
                }
            }
        }

        private void listBoxAddItem(String s){
            if (clientListBox.InvokeRequired)
            {
                clientListBox.Invoke(listBoxAddItemDelegate, s);
            }
            else
            {
                clientListBox.Items.Add(s);
            }
        }

        private void Form1_Closing(object sender, FormClosingEventArgs e)
        {
            listen.Abort();
            socket.Close();
            
        }
    }
}



当客户端强行关闭后,下一次服务器广播消息,当循环到断开链接的Client就会报错。
然后服务器提示有Client断开。

现在我想实现的是,当循环到断开链接的Client报错后,从clientSockets(Socket的List)中删除那个出错的Client。

于是我把广播函数改成了:


        private void boardCast(byte[] buffer,int size)
        {
            List<Socket> delArray = new List<Socket>();
            //遍历发送数据
            foreach (Socket myClient in clientSockets)
            {
                try
                {
                    if (myClient.Connected)
                    {
                        myClient.Send(buffer, 0, size, SocketFlags.None);
                    }

                }
                catch
                {
                    listBoxAddItem("Lost a Client! IP:" + myClient.RemoteEndPoint.ToString());
                    delArray.Add(myClient);
                }
            }
            //删除断开的Socket
            foreach (Socket myClient in delArray)
            {
                clientSockets.Remove(myClient);
            }
        }


结果出现:
集合已修改;可能无法执行枚举操作。

错误指向foreach (Socket myClient in clientSockets)的in

求解一般什么情况才会出现上述错误? --------------------编程问答-------------------- socket还没有完全关闭? 这个我也不懂 同问!
  我出的问题是socket client连接出错断开后自己重新连接可是就是连接不上!一直抱同样的错误,如果重启下客户端就好了!
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,