完整版的Socket服务器端

来源:互联网 发布:fw190d13数据 编辑:程序博客网 时间:2024/05/21 10:35

上次的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);                TxtLogShowMsg(string.Format("已成功连接:" + 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)            {                int count = 0;                                //非正常退出                try                {                    //将接收到的数据,存到缓存区                    //因为Receive方法会阻塞线程,所以也需要用另一个线程来等待                    count = socket.Receive(recByte, 0, recByte.Length, SocketFlags.None);                }                catch                {                    TxtLogShowMsg(string.Format("来自客户端{0}的消息;对方非正常退出了\r\n{1}", socket.RemoteEndPoint, txtLog.Text));                                   }                             //对方正常退出了                if (count <= 0)                {                    TxtLogShowMsg(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);                TxtLogShowMsg(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);                }            }        }        //给txtLog赋值的封装方法        //需要处理跨控件访问的问题        public void TxtLogShowMsg(string str)        {            if (this.txtLog.InvokeRequired)            {                //同步方法                txtLog.Invoke(new FlushSocket(() =>                {                    txtLog.Text = str;                }));            }            else            {                                txtLog.Text = str;            }        }    }
下面是显示效果

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

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


1 1
原创粉丝点击