简单的socket通信加上异步操作(C)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Server
{
    public partial class Form1 : Form
    {
        //这里声明多个套接字是为了在连接,接收数据,发送数据的函数中不发生混乱,同时方便关闭
        public static Socket ServerSocket;    //声明用于监听的套接字
        public static Socket socketAccept;    //声明绑定了客户端的套接字   
        public static Socket socket;    //声明用于与某一个客户端通信的套接字

        public static int SFlag = 0;    //连接成功标志
        public static int CFlag = 0;    //客户端关闭的标志

        Thread th1;     //声明线程1
        Thread th2;     //声明线程2


        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;    //执行新线程时跨线程资源访问检查会提示报错,所以这里关闭检测
        }

        /*****************************************************************/
        
        void Listen(Object sk)
        {
            socketAccept = sk as Socket;    //创建一个与客户端对接的套接字

            try
            {
                while (true)
                {
                    //GNFlag如果为1就进行中断连接,使用在标志为是为了保证能够顺利关闭服务器端
                    /*
                     * 当客户端关闭一次后,如果没有这个标志位会使得服务器端一直卡在中断的位置
                     * 如果服务器端一直卡在中断的位置就不能顺利关闭服务器端
                     */

                    //4.阻塞到有client连接
                    socket = socketAccept.Accept();

                    CFlag = 0;  //连接成功,将客户端关闭标志设置为0
                    SFlag = 1;  //当连接成功,将连接成功标志设置为1

                    richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss  ") + textBox1.Text + "连接成功";
                    richTextBox1.Text += "\r\n";

                    //开启第二个线程接收客户端数据
                    th2 = new Thread(Receive);  //线程绑定Receive函数
                    th2.IsBackground = true;    //运行线程在后台执行
                    th2.Start(socket);    //Start里面的参数是Listen函数所需要的参数,这里传送的是用于通信的Socket对象
                }
            }
            catch
            {
                //MessageBox.Show("没有连接上客户端");   
            }
        }
       

        void Receive(Object sk)
        {
            socket = sk as Socket;  //创建用于通信的套接字

            while (true)
            {
                try
                {
                    if (CFlag == 0 && SFlag == 1)
                    {
                        //5.接收数据
                        byte[] recieve = new byte[1024];
                        int len = socket.Receive(recieve);

                        //6.打印接收数据
                        if (recieve.Length > 0)
                        {
                            //如果接收到客户端停止的标志
                            if (Encoding.ASCII.GetString(recieve, 0, len) == "*close*")
                            {
                                richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss  ") + "客户端已退出" + "\n";
                                CFlag = 1;      //将客户端关闭标志设置为1

                                break;      //退出循环
                            }

                            //打印接收数据
                            richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss  ") + "接收:";
                            richTextBox1.Text += Encoding.ASCII.GetString(recieve, 0, len);  //将字节数据根据ASCII码转成字符串
                            richTextBox1.Text += "\r\n";
                        }
                    }
                    else
                    {
                        break;  //跳出循环
                    }
                }
                catch
                {
                    MessageBox.Show("收不到信息");
                }
            }
        }
      


        private void button_Send(object sender, EventArgs e)
        {
            //SFlag标志连接成功,同时当客户端是打开的时候才能发送数据
            if (SFlag == 1 && CFlag == 0)
            {
                byte[] send = new byte[1024];
                send = Encoding.ASCII.GetBytes(richTextBox2.Text);    //将字符串转成字节格式发送
                socket.Send(send);  //调用Send()向客户端发送数据

                //打印发送时间和发送的数据
                richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss  ") + "发送:";
                richTextBox1.Text += richTextBox2.Text + "\n";
                richTextBox2.Clear();   //清除发送框
            }
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox_Addr(object sender, EventArgs e)
        {

        }

        private void button_Accpet(object sender, EventArgs e)
        {
            ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);     //创建用于通信的套接字

            richTextBox1.Text += "正在连接...\n";
            button1.Enabled = false;  //禁止操作接收按钮

            //1.绑定IP和Port
            IPAddress IP = IPAddress.Parse(textBox1.Text);
            int Port = int.Parse(textBox2.Text);

            //IPAddress ip = IPAddress.Any;
            IPEndPoint iPEndPoint = new IPEndPoint(IP, Port);

            try
            {
                //2.使用Bind()进行绑定
                ServerSocket.Bind(iPEndPoint);
                //3.开启监听
                //Listen(int backlog); backlog:监听数量 
                ServerSocket.Listen(10);

                /*
                 * tip:
                 * Accept会阻碍主线程的运行,一直在等待客户端的请求,
                 * 客户端如果不接入,它就会一直在这里等着,主线程卡死
                 * 所以开启一个新线程接收客户单请求
                 */

                //开启线程Accept进行通信的客户端socket
                th1 = new Thread(Listen);   //线程绑定Listen函数
                th1.IsBackground = true;    //运行线程在后台执行
                th1.Start(ServerSocket);    //Start里面的参数是Listen函数所需要的参数,这里传送的是用于通信的Socket对象
                Console.WriteLine("1");
            }
            catch
            {
                MessageBox.Show("服务器出问题了");
            }
        }

        private void textBox_Port(object sender, EventArgs e)
        {

        }

        private void button_Close(object sender, EventArgs e)
        {
            //若连接上了客户端需要关闭线程2和socket,没连接上客户端直接关闭线程1和其他套接字
            if (CFlag == 1)
            {
                th2.Abort();        //关闭线程2
                socket.Close();     //关闭用于通信的套接字
            }

            ServerSocket.Close();   //关闭用于连接的套接字
            socketAccept.Close();   //关闭与客户端绑定的套接字
            th1.Abort();    //关闭线程1

            CFlag = 0;  //将客户端标志重新设置为0,在进行连接时表示是打开的状态
            SFlag = 0;  //将连接成功标志程序设置为0,表示退出连接
            button1.Enabled = true;
            richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss  ");
            richTextBox1.Text += "服务器已关闭" + "\n";
            MessageBox.Show("服务器已关闭");
        }

        private void richTextBox_Receive(object sender, EventArgs e)
        {

        }

        private void richTextBox_Send(object sender, EventArgs e)
        {

        }

        private void richTextBox2_Send_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)//如果输入的是回车键  
            {
                this.button_Send(sender, e);//触发button事件  
            }
        }
    }
}

在csdn中找到一个socket的文章,但是没有异步操作,本篇文章加上异步操作

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cc_sensii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值