解决方案 »

  1.   

    你能过SOCKET发送接收的是对象还是结构体?
      

  2.   

    在foreach里最好不要删除里面的元素吧
      

  3.   

    socket.Close();
    socket.ShutDown();
      

  4.   

    怎么可以在foreach里面删除元素??
    用for,逆循环,或者用dictionary来存储socket列表.
      

  5.   

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;
    using SGSserver.COMM;
    using SGSserver.Model;
    using System.Linq;
    using System.IO;namespace Server
    {
        public partial class SGSserverForm : Form
        {
            /// <summary>
            /// 当前已连接的客户端信息
            /// </summary>
            class ClientInfo
            {
                public Socket socket;   //Socket of the client
                public string user;  //Name by which the user logged into the chat room
                public int leagueid;
                public byte[] byteData; //byte
            }        //The collection of all clients logged into the room (an array of type ClientInfo)
            static List<ClientInfo> clientList = new List<ClientInfo>();        //The main socket on which the server listens to the clients
            Socket serverSocket;        public SGSserverForm()
            {
                //AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler);
                CheckForIllegalCrossThreadCalls = false;
                InitializeComponent();
            }
            private void SGSserverForm_Load(object sender, EventArgs e)
            {
                try
                {
                    // 实例化套接字
                    serverSocket = new Socket(AddressFamily.InterNetwork,
                                              SocketType.Stream,
                                              ProtocolType.Tcp);                // 初始化IP和端口
                    IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.189"), 10000);                // 绑定IP和端口并开始监听
                    serverSocket.Bind(ipEndPoint);
                    //最大连接数
                    serverSocket.Listen(10000);
                    //serverSocket.Shutdown(SocketShutdown.Both);
                    // serverSocket.Close();
                    // 接受一个传入的连接
                    serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "连接服务器失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }        private void OnAccept(IAsyncResult ar)
            {
                try
                {
                    // 接收一个客户端连接,此连接包含客户端的基本信息。
                    Socket clientSocket = serverSocket.EndAccept(ar);                ClientInfo clientInfo = new ClientInfo();
                    clientInfo.socket = clientSocket;
                    clientInfo.byteData = new byte[1024];
                    //找到列表中的当前socket
                    clientList.Add(clientInfo);                // 重新等待接收下一个新连接。
                    serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);                // 从客户端接收发送的消息
                    clientSocket.BeginReceive(clientInfo.byteData, 0, clientInfo.byteData.Length, SocketFlags.None,
                       new AsyncCallback(OnReceive), clientSocket);
                }
                //处理参数为空引用异常 
                catch (ArgumentNullException ae)
                {
                    MessageBox.Show("处理参数为空引用异常 : {0}", ae.Message);
                }
                //处理操作系统异常 
                catch (SocketException se)
                {
                    MessageBox.Show("处理操作系统异常 : {0}", se.Message);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "连接异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                //catch (Exception ex)
                //{
                //    Shutdown();
                //    //MessageBox.Show(ex.Message, "连接异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
                //}
            }
            private void Shutdown()
            {
                //serverSocket.Shutdown(SocketShutdown.Both);
                serverSocket.Close();
                serverSocket.Dispose();            Application.Restart();
            }
            //用来往richtextbox框中显示消息
            private void showClientMsg(string msg)
            {
                //在线程里以安全方式调用控件
                if (txtLog.InvokeRequired)
                {
                    MyInvoke _myinvoke = new MyInvoke(showClientMsg);
                    txtLog.Invoke(_myinvoke, new object[] { msg });
                }
                else
                {
                    if (txtLog.Lines.Count() > 100)
                    {
                        txtLog.Clear();
                    }
                    txtLog.AppendText(msg);
                }
            }
            public delegate void MyInvoke(string str);
            public void userListOperate(string msg)
            {
                //在线程里以安全方式调用控件
                if (listUser.InvokeRequired)
                {
                    MyInvoke _myinvoke = new MyInvoke(userListOperate);
                    listUser.Invoke(_myinvoke, new object[] { msg });
                }
                else
                {
                    listUser.Items.Add(msg);
                }
            }
            public void userListOperateR(string msg)
            {
                //在线程里以安全方式调用控件
                if (listUser.InvokeRequired)
                {
                    MyInvoke _myinvoke = new MyInvoke(userListOperateR);
                    listUser.Invoke(_myinvoke, new object[] { msg });
                }
                else
                {
                    listUser.Items.Remove(msg);
                }
            }
      

  6.   

    private void OnReceive(IAsyncResult ar)
            {
                // 从客户端套接字中接收信息
                Socket clientSocket = (Socket)ar.AsyncState;
                clientSocket.EndReceive(ar);
                try
                {
                    // 待发送的消息体
                    byte[] message;
                    MessageModel msgToSend = new MessageModel();
                    int currentIndex = -1;
                    //找到列表中的当前socket
                    foreach (ClientInfo client in clientList)
                    {
                        if (client.socket == clientSocket)
                        {
                            currentIndex++;
                            break;
                        }
                        currentIndex++;
                    }
                    if (currentIndex >= 0)
                    {
                        // 将套接字中的二进制数据流转换成String
                        string dataStr = Encoding.UTF8.GetString(clientList[currentIndex].byteData).Replace("\0", "");                    if (dataStr.Contains("policy"))
                        {
                            msgToSend.message = "<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>\0";
                            msgToSend.sender = "";
                            msgToSend.receiver = "";
                            msgToSend.channel = 1;
                            message = Encoding.UTF8.GetBytes(msgToSend.message);
                            //clientList[currentIndex].socket.Send(message);
                            clientList[currentIndex].socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                  new AsyncCallback(OnSend), clientList[currentIndex].socket);                        clientList[currentIndex].byteData = new byte[1024];
                            clientList[currentIndex].socket.BeginReceive(clientList[currentIndex].byteData, 0, clientList[currentIndex].byteData.Length, SocketFlags.None
                                , new AsyncCallback(OnReceive), clientList[currentIndex].socket);
                        }
                        else if (string.IsNullOrEmpty(dataStr))
                        {
                            showClientMsg("【" + clientList[currentIndex].user + "】离开聊天服务器\r\n");                        clientList[currentIndex].socket.Close();
                            userListOperateR(clientList[currentIndex].user);
                            // 移除
                            clientList.RemoveAt(currentIndex);
                            GC.Collect();
                            return;
                        }
                        else
                        {
                            MessageModel msgReceived = DataFactory.GetDataModel(dataStr);
                            showClientMsg("【" + msgReceived.sender + "】:" + msgReceived.message + "\r\n");
                            if (string.IsNullOrEmpty(clientList[currentIndex].user))
                            {
                                clientList[currentIndex].user = msgReceived.sender;
                                clientList[currentIndex].leagueid = msgReceived.leagueid;                            userListOperate(msgReceived.sender);
                                showClientMsg("【" + msgReceived.sender + "】进入聊天服务器\r\n");
                            }
                            // 获得命令类型和用户名
                            msgToSend.message = msgReceived.message;
                            msgToSend.sender = msgReceived.sender;
                            msgToSend.receiver = msgReceived.receiver;
                            msgToSend.channel = msgReceived.channel;                        //1:喇叭全服务器(聊天时扣除一个喇叭) 2:公会 3:私聊 4:系统 5:喊话
                            //txtLog.Text += "[channel:" + msgReceived.channel.ToString() + "]" + msgToSend.message + "\r\n";
                            if (msgReceived.channel == 1 || msgReceived.channel == 4 || msgReceived.channel == 6)
                            {
                                message = Encoding.UTF8.GetBytes(DataFactory.GetByteString(msgToSend));
                                // 获得当前所有的在线用户列表
                                foreach (ClientInfo client in clientList)
                                {
                                    // 发送消息给当前在线的用户
                                    client.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                            new AsyncCallback(OnSend), client.socket);
                                }
                            }
                            else if (msgReceived.channel == 2)
                            {
                                message = Encoding.UTF8.GetBytes(DataFactory.GetByteString(msgToSend));
                                // 获得当联盟用户列表
                                if (msgReceived.leagueid > 0)
                                {
                                    foreach (ClientInfo client in clientList.FindAll(f => f.leagueid == msgReceived.leagueid))
                                    {
                                        // 发送消息给当前联盟的用户
                                        client.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                                new AsyncCallback(OnSend), client.socket);
                                    }
                                }
                            }
                            else if (msgReceived.channel == 3)
                            {
                                message = Encoding.UTF8.GetBytes(DataFactory.GetByteString(msgToSend));
                                foreach (ClientInfo client in clientList)
                                {
                                    // 私聊
                                    if (client.user == msgReceived.receiver)
                                    {
                                        client.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                                new AsyncCallback(OnSend), client.socket);
                                        break;
                                    }
                                }
                                clientList[currentIndex].socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                             new AsyncCallback(OnSend), clientList[currentIndex].socket);
                            }
                            clientList[currentIndex].byteData = new byte[1024];
                            clientList[currentIndex].socket.BeginReceive(clientList[currentIndex].byteData, 0, clientList[currentIndex].byteData.Length, SocketFlags.None
                                , new AsyncCallback(OnReceive), clientList[currentIndex].socket);
                        }
                    }
                } 
                //处理参数为空引用异常 
                catch (ArgumentNullException ae)
                {
                    MessageBox.Show("处理参数为空引用异常 : {0}", ae.Message);
                }
                //处理操作系统异常 
                catch (SocketException se)
                {
                    MessageBox.Show("处理操作系统异常 : {0}", se.Message);
                }
                catch (Exception ex)
                {
                    //Shutdown();
                    MessageBox.Show(ex.Message, "接收异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }        public void OnSend(IAsyncResult ar)
            {
                try
                {
                    Socket client = (Socket)ar.AsyncState;
                    client.EndSend(ar);
                }  //处理参数为空引用异常 
                catch (ArgumentNullException ae)
                {
                    MessageBox.Show("处理参数为空引用异常 : {0}", ae.Message);
                }
                //处理操作系统异常 
                catch (SocketException se)
                {
                    MessageBox.Show("处理操作系统异常 : {0}", se.Message);
                }
                catch (Exception ex)
                {
                    //Shutdown();
                    MessageBox.Show(ex.Message, "发送异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
    }
      

  7.   

    foreach 那出异常了吧,try catch下
      

  8.   

    不要new byte[1024] , C# 内存释放是由.NET自己控制的,内存释放不及时,自然会有问题,试下 Array.Clear(clientList[currentIndex].byteData, 0, clientList[currentIndex].byteData.Length);不用每次都new