首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

c#接受tcp数据 急解决思路

2013-03-13 
c#接受tcp数据 急急急求助各位大侠 我做的接受tcp协议的数据 代码如下IPAddress lacaladdr IPAddress.Pa

c#接受tcp数据 急急急
求助各位大侠 我做的接受tcp协议的数据 代码如下 
 IPAddress lacaladdr = IPAddress.Parse("127.0.0.1");
            int port = Int32.Parse("9086");//本地待侦听端口 
           TcpListener tcpListener = new TcpListener(port);//创建TcpListener对象实例 
           tcpListener.Start();
           TcpClient tcpclient = tcpListener.AcceptTcpClient();
           NetworkStream ns = tcpclient.GetStream();
            StreamReader sr=new StreamReader(ns);
            string reasult = sr.ReadToEnd();
            Invoke(new UpdateDisplayDelegate(UpdateDisplay),new object [] {reasult});
            tcpclient.Close();
            tcpListener.Stop();
为何能够建立连接 却无法接收数据 ?? 提示内容为:-sr.ReadToEnd()“sr.ReadToEnd()”引发了“System.IO.IOException”类型的异常string {System.IO.IOException} base {"无法从传输连接中读取数据: 无法立即完成一个非阻止性套接字操作。。"}System.SystemException {System.IO.IOException}

[解决办法]


    public abstract class PacketTransferBase
    {
        /// <summary>
        /// Socket列表
        /// </summary>
        public SortedList<int, Socket> SocketClientList { get; private set; }       

        public PacketTransferBase()
        {
            SocketClientList = new SortedList<int, Socket>();
        }

        /// <summary>
        /// 保存客户端,以待每次接收后进行判断等功能
        /// </summary>
        /// <param name="socketClient"></param>
        protected void AddClient(Socket socketClient)


        {
            lock (SocketClientList)
            {               
                SocketClientList.Add(socketClient.Handle.ToInt32(), socketClient);
            }           
        }

        /// <summary>
        /// 接收信息
        /// </summary>
        /// <param name="ar"></param>
        protected void ReceiveMessage(IAsyncResult ar)
        {
            Socket socket = null;
            try
            {
                StateObject so = (StateObject)ar.AsyncState;
                socket = so.workSocket;                

                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
                var length = socket.EndReceive(ar);
                if (length == 0)        //接收0字节,说明对方连接已经断开
                {                    
                    Clean(socket);
                    return;
                }
                byte[] actualData = new byte[length];
                Array.Copy(so.buffer, 0, actualData, 0, length);

                bool continueReceive = false;
                continueReceive = OnReceivePacket(actualData, socket);

                //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)                
                if (continueReceive)
                {


                    socket.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveMessage), so);
                }
                else
                {
                    Clean(socket);                   
                }
            }
            catch (Exception ex)
            {                
                if (socket != null)
                {
                    Clean(socket, true);
                }
            }
        }

        private bool OnReceivePacket(byte[] actualData, Socket socket)
        {
            throw new NotImplementedException();
        }
       

        /// <summary>
        /// 从列表中移除Socket,并关闭Socket
        /// </summary>
        /// <param name="socket"></param>
        protected void Clean(Socket socket)
        {           
            int socketHandle = socket.Handle.ToInt32();
            lock (SocketClientList)
            {
                if (SocketClientList.ContainsKey(socketHandle))
                {
                    SocketClientList.Remove(socketHandle);
                }
            }
            socket.Close();            
        }



        protected void Clean(Socket socket, bool disposing)
        {
            if (disposing)
            {                
            }
            Clean(socket);
        }

        /// <summary>
        /// 清理所有Socket资源
        /// </summary>
        /// <param name="disposing">是否发送Socket关闭事件</param>
        public void Clean(bool disposing)
        {
            if (SocketClientList.Count > 0)
            {
                while (SocketClientList.Count > 0)
                {
                    Clean(SocketClientList.Values[0], disposing);
                }
            }
        }
    }

    /// <summary>
    /// TCP服务器端
    /// </summary>
    public class TCPServer : PacketTransferBase
    {
        public string ServerIP { get; set; }
        public int ServerPort { get; set; }
        private static TCPServer tcpServer = new TCPServer();
        Socket socketServer = null;
       
        private TCPServer()
        {           
        }

        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.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)
            {                


            }
        }
    }

    public class StateObject
    {
        public Socket workSocket = null;
        public EndPoint tempRemoteEP = null;
        public static readonly int BUFFER_SIZE = 1024;
        public byte[] buffer = new byte[BUFFER_SIZE];
    }


    /// <summary>
    /// TCP 客户端
    /// </summary>
    public class TCPClient : PacketTransferBase
    {
        public string ServerIP { get; set; }
        public int ServerPort { get; set; }
        private int SocketClientCount { get; set; }
        private static TCPClient tcpClient = new TCPClient();
       
        private TCPClient()
        {            
        }

        public static PacketTransferBase GetInstance()
        {
            return tcpClient;
        }

        public Socket ConnectToServer()
        {
            //创建一个Socket
            Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            
            try
            {
                socketClient.Connect(ServerIP, ServerPort);          
                AddClient(socketClient);               
                //实现接受消息的方法
                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginreceive.aspx
                StateObject so = new StateObject();
                so.workSocket = socketClient;
                socketClient.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveMessage), so);


            }
            catch (Exception ex)
            {               
                socketClient = null;
            }
            return socketClient;            
        }
    }

热点排行