我是学.net的新手,现在遇到了点问题 ,就是套接字的 多个客户端怎样给服务端发送信息 ,服务端是循环接收客户端的连接请求的,现在多个客户端连上后 只能一个客户端给服务端发送。高人请帮助 ,谢谢.net

解决方案 »

  1.   

    服务器socket listen后,accept会生成1个新的连接,每次你都把这个连接给新的对象,就有多个连接,就可以同时接收多个客户端的发送了。
      

  2.   

    服务器端的一个代码例子,包括接收客户端以及接收数据    /// <summary>
        /// 收包处理委托
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="socket"></param>
        /// <returns></returns>
        public delegate bool ReceivePacketHandle(byte[] buffer, Socket socket);    /// <summary>
        /// 客户端接受委托
        /// </summary>
        public delegate void ClientChangedHandle(object state);     public abstract class PacketTransferBase
        {
            /// <summary>
            /// Socket列表
            /// </summary>
            public SortedList<int, Socket> SocketClientList { get; private set; }        /// <summary>
            /// 客户端接收事件
            /// </summary>
            public event ClientChangedHandle OnClientAccepted;        /// <summary>
            /// 客户端关闭事件
            /// </summary>
            public event ClientChangedHandle OnClientClosed;        /// <summary>
            /// 收包处理事件
            /// </summary>
            public event ReceivePacketHandle OnReceivePacket;        public PacketTransferBase()
            {
                SocketClientList = new SortedList<int, Socket>();           
            }        /// <summary>
            /// 保存客户端,以待每次接收后进行判断等功能
            /// </summary>
            /// <param name="socketClient"></param>
            protected void AddClient(Socket socketClient)
            {
                lock (SocketClientList)
                {
                    HYTLogging.NCLogger.GetInstance().WriteInfoLog(string.Format("Add Socket:{0}.{1}", socketClient.Handle, socketClient.Connected));
                    SocketClientList.Add(socketClient.Handle.ToInt32(), socketClient);
                }
                //bufferList.Add(clientCount, new byte[1024]);
                if (OnClientAccepted != null)
                {
                    OnClientAccepted(socketClient.Handle.ToInt32());
                }
            }        /// <summary>
            /// 接收信息
            /// </summary>
            /// <param name="ar"></param>
            protected void ReceiveMessage(IAsyncResult ar)
            {
                try
                {
                    StateObject so = (StateObject)ar.AsyncState;
                    Socket socket = so.workSocket;
                    //var socket = ar.AsyncState as Socket;                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
                    var length = socket.EndReceive(ar);
                    byte[] actualData = new byte[length];
                    Array.Copy(so.buffer, 0, actualData, 0, length);
                    //fileManager.ReceivePacket(actualData);
                    HYTLogging.NCLogger.GetInstance().WriteInfoLog(string.Format("TCPServer.ReceiveMessage: buffer.{0} at Socket.{1} with buffer[23].{2},buffer[24].{3}", length, socket.Handle, so.buffer[23], so.buffer[24]));
                    //fileManager.ReceivePacket(actualData, socket);
                    //FileTransferManagerServer server = FileTransferManagerServer.GetInstance();
                    //server.ReceivePacket(actualData, socket);
                    bool continueReceive = false;
                    if (OnReceivePacket != null)
                    {
                        continueReceive = OnReceivePacket(actualData, socket);
                    }                //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)
                    //socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
                    if (continueReceive)
                    {
                        socket.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveMessage), so);
                    }
                    else
                    {
                        Clean(socket);
                        //socket.Close();
                    }
                }
                catch (Exception ex)
                {
                    HYTLogging.NCLogger.GetInstance().WriteInfoLog(ex.Message + ex.StackTrace);
                }
            }        /// <summary>
            /// 从列表中移除Socket,并关闭Socket
            /// </summary>
            /// <param name="socket"></param>
            protected void Clean(Socket socket)
            {
                HYTLogging.NCLogger.GetInstance().WriteInfoLog(string.Format("Clean Socket:{0}.{1}", socket.Handle, socket.Connected));
                int socketHandle = socket.Handle.ToInt32();
                lock (SocketClientList)
                {
                    if (SocketClientList.ContainsKey(socketHandle))
                    {
                        SocketClientList.Remove(socketHandle);
                    }
                }
                socket.Close();
                if (OnClientClosed != null)
                {
                    OnClientClosed(socketHandle);
                }
            }
        }       /// <summary>
        /// TCP服务器端
        /// </summary>
        public class TCPServer : PacketTransferBase
        {
            public string ServerIP { get; set; }
            public int ServerPort { get; set; }
            
            //public Socket[] SocketClientList { get; private set; }
            
            private static TCPServer tcpServer = new TCPServer();
            Socket socketServer = null;
            //FileManager fileManager = new FileManager(FileControl.FileReceive, TCPModel.TCPServer);
            //FileManager fileManager = new FileManager(FileControl.FileSend, TransferModel.TCPServer);        private TCPServer()
            {
                //SocketClientList = new Socket[10];   
                //SocketClientList = new SortedList<int, Socket>();            
            }        public static PacketTransferBase GetInstance()
            {
                return tcpServer;
            }        /// <summary>
            /// 服务器端建立侦听
            /// </summary>
            public void CreatListener()
            {
                //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
                socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            //将该socket绑定到主机上面的某个端口
                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx
                //socketServer.Bind(new IPEndPoint(IPAddress.Any, 4530));
                socketServer.Bind(new IPEndPoint(IPAddress.Parse(ServerIP), ServerPort));            //启动监听,并且设置一个最大的队列长度
                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx
                socketServer.Listen(100);            //开始接受客户端连接请求
                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept.aspx
                socketServer.BeginAccept(new AsyncCallback(ClientAccepted), socketServer);
            }
            
            /// <summary>
            /// 接收客户端
            /// </summary>
            /// <param name="ar"></param>
            public void ClientAccepted(IAsyncResult ar)
            {
                try
                {
                    var socketServer = ar.AsyncState as Socket;                //这就是客户端的Socket实例,我们后续可以将其保存起来
                    var socketClient = socketServer.EndAccept(ar);    
                    AddClient(socketClient);                //接收客户端的消息(这个和在客户端实现的方式是一样的)                
                    StateObject so = new StateObject();
                    so.workSocket = socketClient;
                    socketClient.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveMessage), so);                 //准备接受下一个客户端请求
                    socketServer.BeginAccept(new AsyncCallback(ClientAccepted), socketServer);
                }
                catch (Exception ex)
                {
                    HYTLogging.NCLogger.GetInstance().WriteInfoLog(ex.Message + ex.StackTrace);
                }
            }
        }    public class StateObject
        {
            public Socket workSocket = null;
            public EndPoint tempRemoteEP = null;
            public const int BUFFER_SIZE = 1024;
            public byte[] buffer = new byte[BUFFER_SIZE];       
        }
      

  3.   

    你把 HYTLogging.NCLogger.GetInstance().....都注释就行,这是我记日志用的
      

  4.   

    当客户端连接上服务器以后  你发送的时候还要用连接的那个tcpclient去发送消息
    而不是重新实例化一个新的tcpclient 你所说的嵌套报错应该是在没有断开的情况下又重新连接了  
    端口号还用的是同一个