Socket套接字做简易聊天室

------- Windows Phone 7手机开发、 .Net培训、期待与您交流! -------

        Socket通信,首先要确定通信方的地址,就像现实中一样,给某人写信首先要有对方的地址,没有地址信都不知道网哪寄也就无法通信了。Socket中的地址是怎样的呢,就是IP地址加端口号,如127.0.0.1:8080这样的格式。比如两台计算机各有一个IP地址,都有装QQ,A要发QQ消息到B首先发到B的IP地址的计算机,但是B计算机上或许有好多网络软件,怎么知道是哪一个的呢,这是端口号就配上用场了,Socket携带的端口信息会匹配程序的端口号,端口号一致的才可以互相通信,这也就是QQ发过来的信息不会显示到MSN上的原因。

        Socket通信需要两个部分,一个服务端,一个客户端。下面是传智博客在讲解Socket是的一个模型



首先在服务端需要有一个Socket进行监听,负责接待的,就相当于一个公司都有前台,前台负责接待但是不用做公司专业型的业务。有人来访,前台负责接待,然后接待的前台再叫一个谈业务的套接字和客户进行沟通。也就是创建一个Socket进行监听,然后客户端Socket连接服务端的服务端的指定端口,服务端监听到客户端的连接后创建一个Socket和客户端Socket通信。

先创建一个服务端的窗体


点击启动服务的时候创建服务端的监听Socket,然后写后面的代码

Thread listenThread = null;//负责监听客户端请求的线程
Socket socketWatch = null;//创建负责监听的套接字
Socket clientSocket = null;//存放监听到客户连接创建的Socket

private void btnBeginListen_Click(object sender, EventArgs e)
        {
            //创建负责监听的套接字,参数(使用IP4寻址协议,使用流式连接,使用TCP协议传输数据)
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //IP地址
            IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
            //创建包含IP和端口的网络节点对象
            IPEndPoint endpoint=new IPEndPoint(address,int.Parse(txtPort.Text.Trim()));
            //将负责监听的套接字绑定到指定IP和端口上
            socketWatch.Bind(endpoint);
            //设置监听队列的容量
            socketWatch.Listen(10);
            
            listenThread = new Thread(WatchConnecting);
            listenThread.IsBackground = true;
            listenThread.Start();

            this.txtMsg.AppendText("服务器启动监听成功!");
        }

void WatchConnecting()
        {
            //开始监听客户端连接请求,Accept方法会阻断当前的线程
            while (true)//持续不断的监听新客户端的连接请求
            {
                Socket socketConnection = socketWatch.Accept();
                //该线程接收客户端发送来的信息
                Thread threadClientMsg = new Thread(ReceiveSocket);
                threadClientMsg.IsBackground = true;
                threadClientMsg.Start(socketConnection);
                clientSocket = socketConnection;
                lbClient.Text = socketConnection.RemoteEndPoint.ToString();
                this.txtMsg.AppendText("客户端连接成功!");
            }
        }

 //接收客户端信息的方法
        void ReceiveSocket(object socket)
        {
            while (true)
            {
                Socket socketClient=socket as Socket;
                byte[] msg = new byte[1024 * 1024 * 2];
                int length =-1;
                try
                {
                    length = socketClient.Receive(msg);//接收客户端发来的信息,返回接收到的字节长度
                }
                catch (SocketException ex)
                {

                    this.txtMsg.AppendText("异常:" + ex.Message);
                    break;
                }
                catch (Exception ex)
                {
                    this.txtMsg.AppendText("异常:" + ex.Message);
                    break;
                }
                string msgtxt = System.Text.Encoding.UTF8.GetString(msg);
                this.txtMsg.AppendText(((Socket)socket).RemoteEndPoint.ToString() + "   " + msgtxt);
            }
        }

然后是发送按钮的事件方法

private void btnSend_Click(object sender, EventArgs e)
        {
            //发送消息到客户端
            string strMsg = txtMsgSend.Text.Trim();
            if (strMsg == "")
            {
                MessageBox.Show("发送内容不能为空!");
                return;
            }
            byte[] arrMsg=System.Text.Encoding.UTF8.GetBytes(strMsg);
            clientSocket.Send(arrMsg);
            this.txtMsg.AppendText(strMsg);
            txtMsgSend.Text = "";
            txtMsgSend.Focus();
        }

服务端就好了,接下来看客户端,客户端与服务端的区别是客户端不需要监听Socket,只需连接服务端的Socket然后进行收发信息。界面和服务端的一样,只是监听按钮改成连接服务端即可。

Thread threadClient = null;//客户端负责接收服务端发送的消息的线程
        Socket socketClient = null;//连接服务端的Socket
        private void btnConnect_Click(object sender, EventArgs e)
        {
            socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
            IPEndPoint endpoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim()));
            try
            {
                socketClient.Connect(endpoint);//连接服务端
            }
            catch 
            {
                MessageBox.Show("服务器拒绝连接!");
                return;
            }


            threadClient = new Thread(ReceiveSocket);
            threadClient.IsBackground = true;
            threadClient.Start();         
        }

接收和发送同服务端的只需用连接的Socket去send()或Receive();

------- Windows Phone 7手机开发、.Net培训、期待与您交流! ------  详细请查看:http://net.itheima.com

你可能感兴趣的:(黑马学习日记)