使用socket异步传输的时,一个用户离开,其他用户的连接都断了,我觉得是服务器代码的原因,但是我看不出来,哪个大侠帮帮忙?using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;namespace UServer
{
    enum Command
    {
        Login,      //Log into the server
        Logout,     //Logout of the server
        Message,    //Send a text message to all the chat clients
        List,       //Get a list of users in the chat room from the server
        Null        //No command
    }    public partial class UServerForm : Form
    {
        //The ClientInfo structure holds the required information about every
        //client connected to the server
        struct ClientInfo
        {
            public EndPoint endpoint;   //Socket of the client
            public string strName;      //Name by which the user logged into the chat room
        }        //The collection of all clients logged into the room (an array of type ClientInfo)
        ArrayList clientList;        //The main socket on which the server listens to the clients
        Socket serverSocket;        byte[] byteData = new byte[1024];
        public UServerForm()
        {
            clientList = new ArrayList();
            InitializeComponent();
        }        private void UServerForm_Load(object sender, EventArgs e)
        {
            try
            {
                CheckForIllegalCrossThreadCalls = false;                //We are using UDP sockets
                serverSocket = new Socket(AddressFamily.InterNetwork,
                    SocketType.Dgram, ProtocolType.Udp);                //Assign the any IP of the machine and listen on port number 1000
                IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1000);                //Bind this address to the server
                serverSocket.Bind(ipEndPoint);                IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
                //The epSender identifies the incoming clients
                EndPoint epSender = (EndPoint)ipeSender;                //Start receiving data
                serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length,
                    SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "UServer",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }        private void OnReceive(IAsyncResult ar)
        {
            try
            {
                IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
                EndPoint epSender = (EndPoint)ipeSender;                serverSocket.EndReceiveFrom (ar, ref epSender);
                
                //Transform the array of bytes received from the user into an
                //intelligent form of object Data
                Data msgReceived = new Data(byteData);                //We will send this object in response the users request
                Data msgToSend = new Data();                byte [] message;
                
                //If the message is to login, logout, or simple text message
                //then when send to others the type of the message remains the same
                msgToSend.cmdCommand = msgReceived.cmdCommand;
                msgToSend.strName = msgReceived.strName;                switch (msgReceived.cmdCommand)
                {
                    case Command.Login:
                        
                        //When a user logs in to the server then we add her to our
                        //list of clients                        ClientInfo clientInfo = new ClientInfo();
                        clientInfo.endpoint = epSender;      
                        clientInfo.strName = msgReceived.strName;                                                clientList.Add(clientInfo);
                        
                        //Set the text of the message that we will broadcast to all users
                        msgToSend.strMessage = msgReceived.strName + " has joined the room!";   
                        break;                    case Command.Logout:                    
                        
                        //When a user wants to log out of the server then we search for her 
                        //in the list of clients and close the corresponding connection
                        int nIndex = 0;
                        foreach (ClientInfo client in clientList)
                        {
                            if (client.endpoint == epSender)
                            {
                                clientList.RemoveAt(nIndex);
                                break;
                            }
                            ++nIndex;
                        }
                        msgToSend.strMessage = msgReceived.strName + " has left the room!";
                        break;                    case Command.Message:                        //Set the text of the message that we will broadcast to all users
                        msgToSend.strMessage = msgReceived.strName + ": " + msgReceived.strMessage;
                        break;                    case Command.List:                        //Send the names of all users in the chat room to the new user
                        msgToSend.cmdCommand = Command.List;
                        msgToSend.strName = null;
                        msgToSend.strMessage = null;                        //Collect the names of the user in the chat room
                        foreach (ClientInfo client in clientList)
                        {
                            //To keep things simple we use asterisk as the er to separate the user names
                            msgToSend.strMessage += client.strName + "*";   
                        }                                                message = msgToSend.ToByte();                        //Send the name of the users in the chat room
                        serverSocket.BeginSendTo (message, 0, message.Length, SocketFlags.None, epSender, 
                                new AsyncCallback(OnSend), epSender);                        
                        break;
                }                if (msgToSend.cmdCommand != Command.List)   //List messages are not broadcasted
                {
                    message = msgToSend.ToByte();                    foreach (ClientInfo clientInfo in clientList)
                    {
                        if (clientInfo.endpoint != epSender || msgToSend.cmdCommand != Command.Login)
                        {
                            //Send the message to all users
                            serverSocket.BeginSendTo (message, 0, message.Length, SocketFlags.None, clientInfo.endpoint, 
                                new AsyncCallback(OnSend), clientInfo.endpoint);                           
                        }
                    }                }                if (msgToSend.cmdCommand == Command.Login || msgToSend.cmdCommand == Command.Logout)
                {
                   listBox1.Items.Add(msgToSend.strMessage + "\r\n");
                }                //If the user is logging out then we need not listen from her
                if (msgReceived.cmdCommand != Command.Logout)
                {
                    //Start listening to the message send by the user
                    serverSocket.BeginReceiveFrom (byteData, 0, byteData.Length, SocketFlags.None, ref epSender, 
                        new AsyncCallback(OnReceive), epSender);
                }
            }
            catch (Exception ex)
            { 
                MessageBox.Show(ex.Message, "UServer", MessageBoxButtons.OK, MessageBoxIcon.Error); 
            }
        }        public void OnSend(IAsyncResult ar)
        {
            try
            {                
                serverSocket.EndSend(ar);
            }
            catch (Exception ex)
            { 
                MessageBox.Show(ex.Message, "UServer", MessageBoxButtons.OK, MessageBoxIcon.Error); 
            }
        }
    }
}

解决方案 »

  1.   

    为你的   if (msgReceived.cmdCommand != Command.Logout) 以及后边的   catch (Exception ex) 写日志或者断点调试。正常的情况下,每一次执行到这里,if 里边的条件应该总为true。
      

  2.   

    OnReceive中,按照不同的枚举,定义一些类(数据处理类,登录/登出处理类,等等),代码有点乱注意try...catch...及写日志
      

  3.   

    第一:serverSocket用的是UDP协议,根本无所谓连接
    第二:serverSocket的send对象是epSender,而epSender绑定的是本机...
    第三:乱...或许是我没看没明白业务...
    建议:MSDN里的Socket就有Client和Server的例子,LZ值得好好看看
      

  4.   

    是不是显示提示框让处理终止了?注释掉看看。
    catch (Exception ex) 
                { 
                    MessageBox.Show(ex.Message, "UServer", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error); 
                } 
      

  5.   

    直接贴的代码都懒得看,太耗眼力了拜托,csdn里面有个贴代码的东东,用那个好不好?
      

  6.   


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.Collections;namespace UServer
    {
        enum Command
        {
            Login,      //Log into the server
            Logout,     //Logout of the server
            Message,    //Send a text message to all the chat clients
            List,       //Get a list of users in the chat room from the server
            Null        //No command
        }    public partial class UServerForm : Form
        {
            struct ClientInfo
            {
                public EndPoint endpoint;   //Socket of the client
                public string strName;      //Name by which the user logged into the chat room
            }        ArrayList clientList;
            Socket serverSocket;
            byte[] byteData = new byte[1024];
            public UServerForm()
            {
                clientList = new ArrayList();
                InitializeComponent();
            }        private void UServerForm_Load(object sender, EventArgs e)
            {
                try
                {
                    CheckForIllegalCrossThreadCalls = false;                serverSocket = new Socket(AddressFamily.InterNetwork,
                        SocketType.Dgram, ProtocolType.Udp);                IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.111"), 8080);                serverSocket.Bind(ipEndPoint);                IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
                    EndPoint epSender = (EndPoint)ipeSender;                serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length,
                        SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "UServer",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }        private void OnReceive(IAsyncResult ar)
            {
                try
                {
                    IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
                    EndPoint epSender = (EndPoint)ipeSender;                serverSocket.EndReceiveFrom (ar, ref epSender);
                    
                    Data msgReceived = new Data(byteData);                Data msgToSend = new Data();                byte [] message;
                    
                    msgToSend.cmdCommand = msgReceived.cmdCommand;
                    msgToSend.strName = msgReceived.strName;                switch (msgReceived.cmdCommand)
                    {
                        case Command.Login:
                            ClientInfo clientInfo = new ClientInfo();
                            clientInfo.endpoint = epSender;      
                            clientInfo.strName = msgReceived.strName;                                                clientList.Add(clientInfo);
                            
                            msgToSend.strMessage = msgReceived.strName + " has joined the room!";
                            listBox1.Items.Add(msgToSend.strMessage + "\r\n");
                            break;                    case Command.Logout:
                            int nIndex = 0;
                            foreach (ClientInfo client in clientList)
                            {
                                if (client.endpoint == epSender)
                                {
                                    clientList.RemoveAt(nIndex);
                                    break;
                                }
                                ++nIndex;
                            }
                            msgToSend.strMessage = msgReceived.strName + " has left the room!";
                            listBox1.Items.Add(msgToSend.strMessage + "\r\n");
                            break;                    case Command.Message:                        msgToSend.strMessage = msgReceived.strName + ": " + msgReceived.strMessage;
                            break;                    case Command.List:                        msgToSend.cmdCommand = Command.List;
                            msgToSend.strName = null;
                            msgToSend.strMessage = null;                        foreach (ClientInfo client in clientList)
                            {
                                msgToSend.strMessage += client.strName + "*";
                            }                        message = msgToSend.ToByte();                        serverSocket.BeginSendTo(message, 0, message.Length, SocketFlags.None, epSender,
                                    new AsyncCallback(OnSend), epSender);                        
                            break;
                    }                if (msgToSend.cmdCommand != Command.List)   //List messages are not broadcasted
                    {
                        message = msgToSend.ToByte();                    foreach (ClientInfo clientInfo in clientList)
                        {
                            if (clientInfo.endpoint != epSender || msgToSend.cmdCommand != Command.Login)
                            {
                                serverSocket.BeginSendTo(message, 0, message.Length, SocketFlags.None, clientInfo.endpoint,
                                    new AsyncCallback(OnSend), clientInfo.endpoint);                           
                            }
                        }                }                if (msgReceived.cmdCommand != Command.Logout)
                    {
                        serverSocket.BeginReceiveFrom (byteData, 0, byteData.Length, SocketFlags.None, ref epSender, 
                            new AsyncCallback(OnReceive), epSender);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "UServer", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }        public void OnSend(IAsyncResult ar)
            {
                try
                {                
                    serverSocket.EndSend(ar);
                }
                catch (Exception ex)
                { 
                    MessageBox.Show(ex.Message, "UServer", MessageBoxButtons.OK, MessageBoxIcon.Error); 
                }
            }
        }
    }