码迷,mamicode.com
首页 > 其他好文 > 详细

完整版的Socket服务器端

时间:2015-04-05 14:41:32      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:socket服务器端

上次的Socket服务器端只是开胃菜,这次我们把上次的代码进行完善和追加。

窗体如下

技术分享

我根据读到的资料,对代码进行了重写

并对源码进行了大量的注释,希望大家能够读懂

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //代理委托
        delegate void FlushSocket();

        //所有代理Socket的集合
        List<Socket> AgentSocketList = new List<Socket>();
        private void btnOpen_Click(object sender, EventArgs e)
        {
            //创建一个Socket对象
            Socket severSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //绑定端口和IP
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text));
            severSocket.Bind(endPoint);
            //开始监听            
            severSocket.Listen(10);

            //用别的线程来连接客户端
            ThreadPool.QueueUserWorkItem(new WaitCallback(CallBackSocket), severSocket);


        }

        //回调函数
        public void CallBackSocket(object obj)
        {
            //将参数obj强转成Socket类型
            Socket severSocket = (Socket)obj;
            //开始连接          
            //主线程会在这里一直阻塞,直到连接到一个客户端
            //返回值是一个代理通信Socket对象

            //可能连接多个客户端,需要循环
            while (true)
            {
                Socket socket = severSocket.Accept();
                //往集合中添加代理Socket
                AgentSocketList.Add(socket);

                //解决跨线程访问控件问题
                if (this.txtLog.InvokeRequired)
                {
                    //FlushSocket fs = new FlushSocket(CallBackSocket);
                    txtLog.Invoke(new FlushSocket(() =>
                    {
                        FlushMsg(socket);
                    }));
                }
                else
                {
                    FlushMsg(socket);
                }

            }
        }

        //显示连接接收情况
        public void FlushMsg(Socket socket)
        {
            txtLog.Text = "已成功连接:" + socket.RemoteEndPoint + "\r\n" + this.txtLog.Text;     
            //接收数据
            ThreadPool.QueueUserWorkItem(new WaitCallback(RecMsgFromClient), socket);
            
        }

        //接收数据
        public void RecMsgFromClient(object obj) 
        {
            Socket socket = (Socket)obj;
            //1M的缓存区
            byte[] recByte = new byte[1024 * 1024];
            while (true)
            {
                //将接收到的数据,存到缓存区
                //因为Receive方法会阻塞线程,所以也需要用另一个线程来等待
                int count = socket.Receive(recByte, 0, recByte.Length, SocketFlags.None);


                //对方退出了
                if (count <= 0)
                {
                    if (this.txtLog.InvokeRequired)
                    {
                        txtLog.Invoke(new FlushSocket(() =>
                        {
                            txtLog.Text = string.Format("来自客户端{0}的消息;对方退出了\r\n{1}", socket.RemoteEndPoint, txtLog.Text);
                        }));
                    }
                    else
                    {
                        //给接收文本框赋值
                        txtLog.Text = string.Format("来自客户端{0}的消息;对方退出了\r\n{1}", socket.RemoteEndPoint, txtLog.Text);
                    }
                    //关闭代理Socket
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();
                    AgentSocketList.Remove(socket);
                    return;
                }


                //将缓存区中的数据转成字符串
                string str = Encoding.Default.GetString(recByte, 0, count);

               

                if (this.txtLog.InvokeRequired)
                {
                    txtLog.Invoke(new FlushSocket(() =>
                    {
                        txtLog.Text = string.Format("来自客户端{0}的内容;{1}\r\n{2}", socket.RemoteEndPoint, str, txtLog.Text);
                    }));
                }
                else
                {
                    //给接收文本框赋值
                    txtLog.Text = string.Format("来自客户端{0}的内容;{1}\r\n{2}", socket.RemoteEndPoint, str, txtLog.Text);
                }
                
            }
        }


        //向客户端发送消息
        private void btnSend_Click(object sender, EventArgs e)
        {
            //遍历每一个代理Socket
            foreach (var socket in AgentSocketList)
            {
                //如果保持连接,就传输数据
                if (socket.Connected)
                {
                    byte[] myBuffer = Encoding.Default.GetBytes(txtSend.Text);
                    socket.Send(myBuffer,0,myBuffer.Length,SocketFlags.None);
                }
            }
        }

    }
下面是显示效果
技术分享

右边的是客户端,大家可以先不用在意,后面我会写客户端的,这里是用的别人的来检验服务器端。

我使用了“123”来进行发送和接收,都没问题,暂没有发现bug


完整版的Socket服务器端

标签:socket服务器端

原文地址:http://blog.csdn.net/langji1234/article/details/44886881

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!