TCP-AcceptSocket

本文深入探讨了TCP连接的实现原理,包括客户端定时连接尝试、数据包丢失处理及服务器端监听、响应机制。详细解释了如何通过Socket进行双向通信,以及在不同场景下数据传输的优化策略。
 1、叙述有点问题:客户端必须先尝试连接,并且不能操作员手工连接,因为不知道服务器的状态,所以客户端有一个定时连接尝试的timer,当然并非倒计时的Timer。另外一个问题:数据包可能丢失,所以服务器告诉客户端每次-1的做法不可靠,应该是发给客户端当前的秒数。

   2、代码:卖过几千元钱的啊

  (1)  客户端:
    public partial class Form1 : Form
    {
        Socket clientSock ;//连接服务器的客户端Socket
        IPAddress serverIp = IPAddress.Parse("127.0.0.1");
        int port = 8000;
        Thread thread;//接收数据的线程

        delegate void SetReceivedToLabelCallBack(string msg,bool isSeconds);//数据接收线程到窗体的跨线程调用委托

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                linkToServer();//连接服务器
            }
            catch (Exception ec)
            {
                MessageBox.Show(ec.Message+",每隔1秒会自动再试");
                timerTryLinkToServer.Enabled = true;
            }
        }

        private void timerTryLinkToServer_Tick(object sender, EventArgs e)
        {
            try
            {
                linkToServer();
                timerTryLinkToServer.Enabled = false;
            }
            catch //不再提示,否则每秒一次,够烦
        }

        private void linkToServer()
        {
            try
            {
                IPEndPoint serverRemote = new IPEndPoint(serverIp, port);
                clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSock.Connect(serverRemote);

                thread = new Thread(new ThreadStart(receiveThread));
                thread.Start();
                MessageBox.Show("linked");
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        private void receiveThread()
        {
            try
            {
                while (true)
                {
                    byte[] buffer = new byte[8];
                    int receivedBytesCount=clientSock.Receive(buffer);
                    string receivedStr = System.Text.Encoding.Unicode.GetString(buffer);
                    if (receivedBytesCount == 4)//发来的是4字节int数据
                    {
                        DisplayReceivedMsg(receivedStr,true);
                    }
                    else//发来的是字符串“1”,非4字节
                    {
                        DisplayReceivedMsg(receivedStr,false);
                    }
                }
            }
            catch(Exception ec)
            {
                MessageBox.Show(ec.Message);
            }
        }

        public void DisplayReceivedMsg(string msg,bool isSeconds)
        {
            Label label=null;
            if (isSeconds)
            {
                label = label1;
            }
            else
            {
                label = label2;
            }
        
            if (label.InvokeRequired)//如果是跨线程调用
            {
                SetReceivedToLabelCallBack  d = new SetReceivedToLabelCallBack(DisplayReceivedMsg);
                this.Invoke(d, new object[] );
            }
            else
            {
                label.Text = msg;
            }
        }
//好习惯,关闭套接字
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (thread != null)
            {
                thread.Abort();
                thread = null;
            }
            if (clientSock != null)
            {
                clientSock.Close();
                clientSock = null;
            }
        }

    }
  (2)服务器端:
     public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        IPAddress serverIp = IPAddress.Parse("127.0.0.1");
        int port = 8000;
        Socket listenSock;
        
        ArrayList clientSockets = new ArrayList();//保存客户端连接的Socket
        System.Timers.Timer timer = new System.Timers.Timer();

        int seconds = 0;
        bool blockSocket=false;//是否停止监听(不接受客户)
        Thread thListen;//监听线程

        private void Form1_Load(object sender, EventArgs e)
        {
            IPEndPoint local = new IPEndPoint(serverIp, port);
            listenSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listenSock.Bind(local);
            listenSock.Listen(50);

            if (listenStart())
            {
                timer.Interval = 1000;
                timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
                timer.Enabled = true;
            }
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            seconds++;
            if (seconds==5)
            {
                listenStop();
                MessageBox.Show("Stop");
                return;
            }
            if(seconds==45)
            {
                if (listenStart())
                    MessageBox.Show("Start");
                else MessageBox.Show("startError");

                send("1");
                seconds = 0;
                return;
            }
            if(seconds<45 && seconds>5)
            {
                send((45 - seconds).ToString());
            }
        }

        private void listenStop()
        {
            try
            {
                blockSocket = true;
                if (thListen != null)
                {
                    thListen.Abort();
                    thListen = null;
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        private bool listenStart()
        {
            try
            {
                thListen = new Thread(new ThreadStart(listenThread));
                thListen.Start();
                return true;
            }
            catch (Exception ec)
            {
                MessageBox.Show(ec.Message);
                return false;
            }
        }

        private void listenThread()
        {
            try
            {
                while (!blockSocket)
                {
                    Socket sock = listenSock.Accept();
                    if (clientSockets.IndexOf(sock) < 0)
                    {
                        clientSockets.Add(sock);
                        MessageBox.Show("built one");
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        private void send(string msg)
        {
            foreach (Socket sock in clientSockets)
            {
                try
                {
                    byte[] buffer = System.Text.Encoding.Unicode.GetBytes(msg);
                    sock.SendTimeout = 500;
                    sock.Send(buffer);
                    MessageBox.Show("send "+msg);
                }
                catch (Exception ec)
                {
                    MessageBox.Show(ec.Message);
                }
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (thListen!= null)
            {
                thListen.Abort();
                thListen = null;
            }
            if (listenSock != null)
            {
                listenSock.Close();
                listenSock = null;
            }
                for (int i = 0; i < clientSockets.Count; i++)
                {
                    Socket sock = (Socket)clientSockets[i];
                    sock.Close();
                }
        }
    }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值