socket通信问题

2015年12月11日 14:55:04 yiqijinbu 阅读数:3035

TCP:面向连接的,所以在服务端绑定端口后,需要监听Listen()是否有客户端发送请求,有的话,Accept()建立一个新的socket对象,用于发送和接收信息,

            就想先建造了一条高速路,再建造一辆货车拉货。

UDP:无连接的,所以在服务端绑定端口后,不需要监听Listen(),也不用建立一个新的socket对象用于接收发送信息,但是在发送和接收时,要讲本身的端口

   做参数发送给对方,这样在交流时,对方才能确定自己。

 

UDP协议:

Client端:

static void Main(string[] args)
        {
            int port = 2001;
            string strHost = GetAddressIP();// "127.0.0.1";
            //  建立IP对象
            IPAddress ip = IPAddress.Parse(strHost);
            //  建立端口对象
            IPEndPoint ipe = new IPEndPoint(ip, port);
 
 
            //  创建socket对象
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            Console.WriteLine("连接中。。。");
 
 
            //  向服务器发送消息
            string strMsgToServe = "嗨,来自客户端的问候。。。";
            //  转成二进制发送到服务端
            byte[] bytMsgToServe = Encoding.UTF8.GetBytes(strMsgToServe);
            socket.SendTo(bytMsgToServe, bytMsgToServe.Length, SocketFlags.None, ipe);
            Console.WriteLine("消息已发送。。。");
 
 
            //IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint Remote = new IPEndPoint(IPAddress.Any, 0);//(EndPoint)sender;
            bytMsgToServe = new byte[1024];
            int recv = socket.ReceiveFrom(bytMsgToServe, ref Remote);//接受来自服务器的数据
 
 
            Console.WriteLine("Message received from{0}:", Remote.ToString());
            Console.WriteLine("收到的服务端消息:"+Encoding.UTF8.GetString(bytMsgToServe, 0, recv));
            socket.Close();
            Console.ReadLine();
        }
 
 
        /// <summary>
        /// 获取本地IP地址信息
        /// </summary>
        public static string GetAddressIP()
        {
            ///获取本地的IP地址
            string AddressIP = string.Empty;
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                {
                    AddressIP = _IPAddress.ToString();
                }
            }
            return AddressIP;
        }


Server端:

static void Main(string[] args)
        {
            int port = 2001;
            string strHost = GetAddressIP();// "127.0.0.1";
            //  创建终结点
            IPAddress ip = IPAddress.Parse(strHost);
            //  创建网络端口
            IPEndPoint ipe = new IPEndPoint(ip, port);
 
            //  创建socke,开始监听--SocketType枚举
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            //  绑定端口
            socket.Bind(ipe);
            Console.WriteLine("等待客户端连接。。。");
 
            //IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);//定义要发送的计算机的地址
            EndPoint Remote = new IPEndPoint(IPAddress.Any, 0);//(EndPoint)(sender);
 
            //  收到的二进制byte
            byte[] bytRecv = new byte[1024];
            int intBytes = socket.ReceiveFrom(bytRecv, ref Remote);//接受来自服务器的数据          
            //Console.WriteLine("Message received from{0}:", Remote.ToString());
            Console.WriteLine("收到的信息:-"+Encoding.UTF8.GetString(bytRecv, 0, intBytes));
 
            string welcome = "Welcome to my test server!";
            bytRecv = Encoding.ASCII.GetBytes(welcome);
            socket.SendTo(bytRecv, bytRecv.Length, SocketFlags.None, Remote);
            Console.ReadLine();
        }
        /// <summary>
        /// 获取本地IP地址信息
        /// </summary>
        public static string GetAddressIP()
        {
            ///获取本地的IP地址
            string AddressIP = string.Empty;
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                {
                    AddressIP = _IPAddress.ToString();
                }
            }
            return AddressIP;
        }

当将服务层写成window服务时,如果客户端关闭,服务端会报错,“远程主机关闭了一个现有的链接”,然后整个服务都停止了。

解决办法:为socket对象设置低级操作模式

//  为 Socket 设置低级操作模式,不然当客户端关闭的时候,会报错
            uint IOC_IN = 0x80000000;
            uint IOC_VENDOR = 0x18000000;
            uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
            socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);

另外,在window服务中,定时控件是不能用的,但是也不报错,不提醒,如果要定时循环,

解决办法:

            System.Timers.Timer tmrSelectCOM = new System.Timers.Timer(2000);
            tmrSelectCOM.Elapsed += new System.Timers.ElapsedEventHandler(tmrSelectCOM_Tick);
            tmrSelectCOM.Enabled = true;

TCP协议:

服务端:

static void Main(string[] args)
        {
            //  ip地址,端口
            int port = 2000;
            string strIp = GetAddressIP();
            //  IP对象
            IPAddress ip = IPAddress.Parse(strIp);
            IPEndPoint ipe = new IPEndPoint(ip, port);
            //  实例化socket对象
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //  绑定端口
            socket.Bind(ipe);
            //  监听
            socket.Listen(0);
            //  为发送请求的客户端创建新的socket对象
            Socket temp = socket.Accept();
 
            //  接收消息
            byte[] bytRecv = new byte[1024];
            int intCount = temp.Receive(bytRecv,bytRecv.Length,0);
            string strRecv = Encoding.UTF8.GetString(bytRecv, 0, intCount);
            Console.WriteLine(strRecv);
 
            //  发送消息
            string strSendMsg = "来自服务端的问候。。。";
            byte[] bytSendMsg = Encoding.UTF8.GetBytes(strSendMsg);
            temp.Send(bytSendMsg, 0, bytSendMsg.Length, 0);
            Console.WriteLine("服务端消息已发送。。。");
            Console.ReadLine();
        }
 
        private static string GetAddressIP()
        {
            string strAddressIP = string.Empty;
            foreach (IPAddress address in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (address.AddressFamily.ToString() == "InterNetwork")
                {
                    strAddressIP = address.ToString();
                }
            }
            return strAddressIP;
        }
  1. 客户端:
public static void Main(string[] args)
        {
            int port = 2000;
            string strIp = GetAddressIP();
            //  IP对象
            IPAddress ip = IPAddress.Parse(strIp);
            IPEndPoint ipe = new IPEndPoint(ip, port);
            //  创建socket对象
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //  连接
            socket.Connect(ipe);
            Console.WriteLine("已连接。。。");
 
            //  发送信息
            string strSendMsg="来自客户端的问候。。。";
            byte[] bytSendMsg = Encoding.UTF8.GetBytes(strSendMsg);
            socket.Send(bytSendMsg, 0, bytSendMsg.Length, SocketFlags.None);
            Console.WriteLine("消息已发送。。。");
            //  接收
            byte[] bytRecvMsg = new byte[1024];
            int intCount = socket.Receive(bytRecvMsg);
            string strRecvMsg = Encoding.UTF8.GetString(bytRecvMsg, 0, intCount);
            Console.WriteLine(strRecvMsg);
            Console.ReadLine();
        }
 
        private static string GetAddressIP()
        {
            //  获取本地的IP地址
            string AddressIP = string.Empty;
            foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
                {
                    AddressIP = _IPAddress.ToString();
                }
            }
            return AddressIP;
        }

TCP图:

socket通信问题

UDP图:

socket通信问题