c#socket简单通信(windows窗体应用程序)

界面布局我就不详细说了,直接看后台代码:

界面:


代码:

一些定义:

        private Socket serverSocket;   //服务器端的socket
        private Thread serverThread;   //服务器端线程
        
        //保存已连接的客户端socket
        private List<Socket> clientSocketList;

        //保存已开启的接收数据的客户端线程
        private List<Thread> clientThreadList;

        private byte[] result = new byte[1024];
        Action<String> AsyncUIDelegate;
        private string IP = "";
        private int Port;

方法:

初始化:

        //初始化界面元素
        private void initView()
        {
            //初始化ip下拉框
            string[] ipAddress = getLocalAddress();
            for (int i = 0; i < ipAddress.Length; i++)
            {
                cboIp.Items.Add(ipAddress[i]);
            }
            //设置下拉框初始值
            cboIp.SelectedIndex = 1;

            //设置端口号
            tbPort.Text = "8990";

            //初始化按钮状态
            btnStart.Enabled = true;
            btnStop.Enabled = false;

            //初始化端口号和IP
            IP = cboIp.SelectedItem.ToString();
            Port = Int32.Parse(tbPort.Text.ToString());


            //在子线程中更新界面元素
            AsyncUIDelegate = delegate(string message)
            {
                addMonitorMessage(message);
            };

            addMonitorMessage("服务器初始化成功!");
        }

获取本机的IP地址:

        //获取本地IP地址
        private string[] getLocalAddress()
        {
            //获取主机名
            string hostName = Dns.GetHostName();

            //根据主机名查找
            IPHostEntry ipHostEntry = Dns.GetHostEntry(hostName);
            string[] result = new string[ipHostEntry.AddressList.Length];
            int i = 0;
            foreach (IPAddress ipAddress in ipHostEntry.AddressList)
            {
                result[i] = ipAddress.ToString();
                i++;
            }
            return result;
        }
开启服务器的监听线程:

        //开启服务器服务
        private void startServer()
        {


            //初始化客户端socket管理列表
            clientSocketList = new List<Socket>();

            //初始化客户端线程管理列表
            clientThreadList = new List<Thread>();

            IPAddress ipAddress = IPAddress.Parse(IP);
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(new IPEndPoint(ipAddress, Port));  //绑定IP地址和端口
            serverSocket.Listen(10);//设置最多是个连接排队请求
            serverThread = new Thread(ListenerClientConnect);
            serverThread.Start();
            tbMonitor.Invoke(AsyncUIDelegate, "服务器启动成功!");
        }

监听客户端的连接:

        //监听客户端连接
        private void ListenerClientConnect()
        {
            while (true)
            {
                Socket clientSocket = serverSocket.Accept();

                //向列表中添加客户端socket
                clientSocketList.Add(clientSocket);

                tbMonitor.Invoke(AsyncUIDelegate, "监听到一个连接");
                //向客户端发送信息
                //使用操作系统当前的编码方式编码
                clientSocket.Send(Encoding.Default.GetBytes("连接成功!"));
                Thread receiverMessage = new Thread(receiverData);

                //向列表中添加客户端线程
                clientThreadList.Add(receiverMessage);

                receiverMessage.Start(clientSocket);
            }
        }

接收客户端发来的信息:

        //接收客户端信息
        private void receiverData(Object clientSocket)
        {
            Socket myClientSocket = (Socket)clientSocket;

            while (true)
            {
                try
                {
                    //服务器端接收消息可能会一直阻塞在Receiver()方法
                    int receiverNum = myClientSocket.Receive(result);
                    string message = Encoding.ASCII.GetString(result, 0, receiverNum);
                    //这里需要判断收到的信息是不是为空,如果为空说明客户端主动断开连接,此时可能受到多条空字符串,所以需要break
                    if ("".Equals(message))
                    {
                        tbMonitor.Invoke(AsyncUIDelegate, "客户端断开连接!");
                        break;
                    }
                    else
                    {
                        tbMonitor.Invoke(AsyncUIDelegate, "收到的信息:" + message);
                    }
                }
                catch (Exception)
                {
                    //myClientSocket.Shutdown(SocketShutdown.Both);
                    myClientSocket.Close();
                    break;
                }
            }
        }

停止服务端和向文本框中添加文本:

        //停止服务
        private void stopServer()
        {
            //这两行的位置不能颠倒,颠倒程序会卡死在这,具体卡死的原因还不清楚
            serverSocket.Close();
            serverThread.Abort();

            for (int i = 0; i < clientSocketList.Count; i++)
            {
                clientSocketList[i].Disconnect(true);
            }

            for (int i = 0; i < clientThreadList.Count; i++)
            {
                clientThreadList[i].Abort();
            }


                tbMonitor.Invoke(AsyncUIDelegate, "服务器关闭!");
        }


添加文本信息:

 private void addMonitorMessage(string message)
        {
            if ("".Equals(tbMonitor.Text))
            {
                tbMonitor.Text = message + "\r\n";
            }
            else
            {
                tbMonitor.Text += message + "\r\n";
            }
        }

剩余的其他简单功能:

        //开始按钮
        private void btnStart_Click(object sender, EventArgs e)
        {
            addMonitorMessage("正在开启服务器......");
            startServer();
            btnStart.Enabled = false;
            btnStop.Enabled = true;

        }

       private void btnStop_Click(object sender, EventArgs e)
        {
            addMonitorMessage("正在关闭服务器......");
            stopServer();
            btnStart.Enabled = true;
            btnStop.Enabled = false;
        }

        private void cboIp_SelectedIndexChanged(object sender, EventArgs e)
        {
            IP = cboIp.SelectedItem.ToString();
        }

        private void tbPort_TextChanged(object sender, EventArgs e)
        {
            Port = Int32.Parse(tbPort.Text.ToString());
        }


最终可以进行测试。有任何问题还请评论告诉我,这只是简单的socket通信,很多地方做的还不完善,会出现某些异常,但是正常情况下通信是没有问题,还有一些未处理的异常请见谅!


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值