Socket的重要性

来源:互联网 发布:刀塔传奇 数据 编辑:程序博客网 时间:2024/05/16 12:52
     Socket不仅在聊天应用程序中需要用到,而且对于学习Asp.net也非常有帮助。你懂得!
     实现服务端和客户端互发信息,以及服务端向多个客户端发送信息。
     服务端代码1:
        public Form1()        {            InitializeComponent();            Control.CheckForIllegalCrossThreadCalls = false;        }        //创建监听用的socket        private void btnStartMonitor_Click(object sender, EventArgs e)        {            //监听的ip地址            IPAddress ip = IPAddress.Parse(txtIP.Text);            //监听的ip地址和端口号            IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPortNumber.Text));            //监听用的socket            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            //通常每个套接字地址(协议/网络地址/端口)只允许使用一次            //绑定监听的ip地址和端口号            socket.Bind(point);            //监听端口   监听队列的长度:同一个时间等待的个数。            socket.Listen(10);            //点击之后,禁用掉按钮            btnStartMonitor.Enabled = false;            //提示用户程序开始运行了            ShowMsg("开始运行了...");            //监听端口,如果有客户端连接,创建通信用socket            //阻塞窗体的运行            //Socket connSocket = socket.Accept();            //用线程来解决窗体假死的问题            Thread th = new Thread(Listen);            th.IsBackground = true;//后台线程            th.Start(socket);        }        //监听是否有客户端连接        void Listen(object o)        {            //监听用的socket            Socket socket = o as Socket;            //监听端口            Socket connSocket = socket.Accept();            //显示远程连接的IP地址和端口号            ShowMsg(connSocket.RemoteEndPoint.ToString());        }         //在文本框显示信息        void ShowMsg(string msg)        {            txtShowMessage.AppendText(msg + "\r\n");        }
     以上代码只能让一个客户端连接服务端,弊端。
     服务端代码2完善——循环接收客户端连接
        //监听是否有客户端连接       void Listen(object o)        {            //监听用的socket            Socket socket = o as Socket;            //可以不停地接受客户端的连接            while (true)            {                //负责通信用的socket                Socket connSocket = socket.Accept();                //显示远程连接的IP地址和端口号                ShowMsg(connSocket.RemoteEndPoint.ToString());                //本机的IP地址和端口号                //connSocket.LocalEndPoint                //接收数据                byte[] buffer = new byte[1024 * 1023];                //接收数据,把数据发到buffer中                //num是实际接收到的字节个数                int num=connSocket.Receive(buffer);                //把实际有效的字节转换成字符串                string str = Encoding.UTF8.GetString(buffer, 0, num);                ShowMsg(str);            }        }
     服务端代码3完善——循环接收消息
        //监听是否有客户端连接       void Listen(object o)        {            //监听用的socket            Socket socket = o as Socket;            //可以不停地接受客户端的连接            while (true)            {                //负责通信用的socket                Socket connSocket = socket.Accept();                //显示远程连接的IP地址和端口号                ShowMsg(connSocket.RemoteEndPoint.ToString());                //本机的IP地址和端口号                //connSocket.LocalEndPoint                //接收数据                byte[] buffer = new byte[1024 * 1023];                //接收数据,把数据发到buffer中                //num是实际接收到的字节个数                int num=connSocket.Receive(buffer);                //把实际有效的字节转换成字符串                string str = Encoding.UTF8.GetString(buffer, 0, num);                ShowMsg(str);            }        }
     服务端代码4完善——循环多个客户端并接收信息:
        //监听是否有客户端连接        void Listen(object o)        {            //监听用的socket            Socket socket = o as Socket;            //可以不停地接受客户端的连接            while (true)            {                //负责通信用的socket                Socket connSocket = socket.Accept();                //显示远程连接的IP地址和端口号                ShowMsg(connSocket.RemoteEndPoint.ToString());                //本机的IP地址和端口号                //connSocket.LocalEndPoint                //线程接收信息                Thread th = new Thread(RecMsg);                th.IsBackground = true;                th.Start(connSocket);            }        }        //接收信息        void RecMsg(object o)        {            //通信用的socket            Socket connSocket = o as Socket;            //可以不停地接受客户端的内容            while (true)            {                //接受数据                byte[] buffer = new byte[1024 * 1024];                //接受数据,把数据发到buffer中                //num就是实际接受到的字节个数                int num = connSocket.Receive(buffer);//当telnet关闭,会不停的发送空(0)字节                //把实际有效的字节转化成字符串                string str = Encoding.UTF8.GetString(buffer, 0, num);                ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + str);                }            }        }
     服务端代码5完善——限制客户端连接数:
        //限制连接客户端的个数        int count=0;        void Listen(object o)        {            //监听用的socket            Socket socket = o as Socket;            //可以不停地接受客户端的连接            while (count<1000)            {                //负责通信用的socket                Socket connSocket = socket.Accept();                //显示远程连接的IP地址和端口号                ShowMsg(connSocket.RemoteEndPoint.ToString());                //本机的IP地址和端口号                //connSocket.LocalEndPoint                //线程接收信息                Thread th = new Thread(RecMsg);                th.IsBackground = true;                th.Start(connSocket);}        }
     服务端代码6完善——解决“当tenet关闭,会不停地发送空(0)字节”:
        //接收信息        void RecMsg(object o)        {            //通信用的socket            Socket connSocket = o as Socket;            //可以不停地接受客户端的内容            while (true)            {                //接受数据                byte[] buffer = new byte[1024 * 1024];                //接受数据,把数据发到buffer中                //num就是实际接受到的字节个数                int num = connSocket.Receive(buffer);//当telnet关闭,会不停的发送空(0)字节                    //当telnet关闭,会不停的发送(0)个字节  客户端断开                    if (num == 0)                    {                        ShowMsg(connSocket.RemoteEndPoint.ToString() + ":退出");                        connSocket.Shutdown(SocketShutdown.Receive);                        connSocket.Close();                        break;                    }                //把实际有效的字节转化成字符串                string str = Encoding.UTF8.GetString(buffer, 0, num);                ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + str);                }            }        }
     客户端代码1:
        public Form1()        {            InitializeComponent();            Control.CheckForIllegalCrossThreadCalls = false;        }        //连接服务端和发送信息都要用到同一个socket,将其定义到外边        Socket socket;        //连接服务端        private void btnConnect_Click(object sender, EventArgs e)        {            //客户端连接服务器的ip地址            IPAddress ip = IPAddress.Parse(txtIP.Text);            //客户端连接的服务器的ip地址和端口号            IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPortNumber.Text));            //创建连接使用的socketsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            try            {                //连接聊天服务器                //服务器没开报错                //由于目标计算机积极拒绝,无法连接。                socket.Connect(point);                ShowMsg("连接成功");            }            catch (Exception ex)            {                ShowMsg(ex.Message);            }        }        void ShowMsg(string msg)        {            txtShowMessage.AppendText(msg + "\r\n");        }        //发送消息        private void btnSendMessage_Click(object sender, EventArgs e)        {            if (socket != null)            {                byte[] buffer = Encoding.UTF8.GetBytes(txtInputMessage.Text);                socket.Send(buffer);            }            else            {                MessageBox.Show("请先连接");            }        }
     客户端代码7完善——服务端知道客户端关闭的消息:
        //接收信息        void RecMsg(object o)        {            //通信用的socket            Socket connSocket = o as Socket;            //可以不停地接受客户端的内容            while (true)            {                //接受数据                byte[] buffer = new byte[1024 * 1024];                //接受数据,把数据发到buffer中                //num就是实际接受到的字节个数                int num = -1;                try                {        //远程主机强迫关闭了一个现有的连接。  当客户端关闭,服务端未关闭时,报错。                    num = connSocket.Receive(buffer);                    //当telnet关闭,会不停的发送(0)个字节  客户端断开                    if (num == 0)                    {                        ShowMsg(connSocket.RemoteEndPoint.ToString() + ":退出");                        connSocket.Shutdown(SocketShutdown.Receive);                        connSocket.Close();                        break;                    }                    //把实际有效的字节转化成字符串                    string str = Encoding.UTF8.GetString(buffer, 0, num);                    ShowMsg(connSocket.RemoteEndPoint.ToString() + ":" + str);                }                catch (Exception ex)                {                    ShowMsg(ex.Message);                    //出现异常,跳出循环                    break;                }            }        }
     服务端代码8完善——服务端给客户端发送消息:
        //发送消息        private void btnSendMessage_Click(object sender, EventArgs e)        {            if (connSocket!=null)            {                byte[] buffer = Encoding.UTF8.GetBytes(txtInputMessage.Text);                try                {                    connSocket.Send(buffer);                }                catch (Exception ex)                {                    ShowMsg(ex.Message);                }            }        }
     客户端代码2完善——客户端接收服务端发送的消息:
        //接收消息        void RecMsg()        {            while (true)            {                byte[] buffer = new byte[1024 * 1024];                try                {                    int num = socket.Receive(buffer);                    string str = Encoding.UTF8.GetString(buffer, 1, num );                    ShowMsg(str);                }                catch (Exception ex)                {                    ShowMsg(ex.Message);                    break;                }            }        }//由于接收消息是一个死循环,需要用到线程                //线程接受消息                Thread th = new Thread(RecMsg);                th.IsBackground = true;                th.Start();
     服务端代码9完善——服务端给指定客户端发送消息:
        //存储通信用的socket字典        Dictionary<string, Socket> dic = new Dictionary<string, Socket>();        //限制连接客户端的个数        int count = 0;        //监听是否有客户端连接        void Listen(object o)        {            //监听用的socket            Socket socket = o as Socket;            //可以不停地接受客户端的连接            while (count < 100)            {                count++;                //监听端口,如果有客户端连接,创建通信用socket                Socket connSocket = socket.Accept();                //显示远程连接的IP地址和端口号                ShowMsg(connSocket.RemoteEndPoint.ToString());                //本机的IP地址和端口号                //connSocket.LocalEndPoint                //保存当前登录的客户端的socket                string ipport = connSocket.RemoteEndPoint.ToString();                cboUser.Items.Add(ipport);                dic.Add(ipport, connSocket);                //线程接收信息                Thread th = new Thread(RecMsg);                th.IsBackground = true;                th.Start(connSocket);            }        }        //发送消息        private void btnSendMessage_Click(object sender, EventArgs e)        {            //获取下拉框中选择的ip和端口号            string ipport = cboUser.Text;            if (!string.IsNullOrEmpty(ipport))            {                byte[] buffer = Encoding.UTF8.GetBytes(txtInputMessage.Text);                try                {                    //根据key获得socket                    Socket connSocket = dic[ipport];                    connSocket.Send(buffer);                }                catch (Exception ex)                {                    ShowMsg(ex.Message);                }            }            else            {                MessageBox.Show("请选择客户端");            }        }
     由于还有文件发送、消息震动等功能,代码太多。

     附上代码完整资源

     备注:写于2013年9月21日

0 0
原创粉丝点击