WinCE Socket的陷阱

摘要:

    在做桑達PDA盤點功能。基本功能已經完成,最近想在門店部署WIFI,然後通過WIFI直接也數據庫通信,將數據實時存入數據庫。一是爲了減少盤點結束後再手工導入的麻煩,並節省大量時間。回收一臺數據大概需要30秒,這30秒並不是設備慢,而是需要人工拿設備並放在底座上,浪費了太多無功時間。二是爲了實時看到盤點結果。在後臺能夠實時看到盤點結果,分析盤點原因,並且能夠知道盤點進度以及還需要多長時間能夠完工。

    爲了實現這目的。臨時的解決方案(測試程序用)是先在資訊室安裝WIFI,將PDA拿到資訊室後,再連接WIFI傳輸數據。徹底的解決方案是在賣場佈置WIFI,全面覆蓋。

正文:

    軟件環境,WinCE5.0,後臺VS2008。下面說說在程序測試中遇到的問題。

一、連接服務器後,第一條數據會丟失。

測試數據是21條商品資料, 連接服務器後,開始傳輸數據。第一次傳輸,第一條數據總是丟失,變成了20條。再測試第二次傳輸時,所有數據又都能接收到,一切正常,21條數據全部回收。把同樣的代碼放在Winform上,在電腦上測試一切正常。

分析原因及解決方法

                1、是TCP連接後立馬進行數據傳輸,TCP把這些數據當成費數據給作廢了。解決辦法,TCP連接後第一次傳輸了一條無用的費數據。

                 2、也可能是這時候網絡鏈路還沒建立暢通。所以就等待網絡,延遲一秒鐘。

        兩種方法都可以解決問題,但我認爲第二種方法是正確的,符合網絡工作原理,也更優雅。代碼如下

            //定義主機的IP及端口
            ip = IPAddress.Parse(App.Instance().serverip);//172.16.20.11"192.169.1.120"
            //MessageBox.Show(ip.ToString());
            ipEnd = new IPEndPoint(ip, 5632); //5566

            _socket.BeginConnect(ipEnd, connectedCallback, _socket);//異步連接

           byte[] cmd = Encoding.UTF8.GetBytes(dataStr);
            _socket.Send(cmd);//發送

       static void connectedCallback(IAsyncResult iar)//異步連接的回調
        {
                Socket client = (Socket)iar.AsyncState;
                try
                {
                    client.EndConnect(iar);
                }
                catch (Exception e)
                {
                    SockErrorStr = e.ToString();
                }
        }

       文檔寫到這裏突然想到,我的連接方式是異步。那麼是否改爲同步連接就不存在此問題呢?馬上測試,第三個解決辦法出來。

              3、採用同步方式與服務器建立連接,於傳輸數據就不會丟失了。

              將_socket.BeginConnect(ipEnd, connectedCallback, _socket);//異步連接改爲

                _socket.Connect(ipEnd); //同步連接

二、服務端斷開後再打開,這時客戶端開始傳數據,顯示傳輸成功,但是服務端一條數據也沒有收到。

       原因沒有想明白。解決辦法是向服務器傳輸數據後,等待服務順返回結果。這樣當服務沒有返回結果時,客戶端會報錯,就可以強制客戶端再連接服務器,完成數據的正確傳輸。

         int bytesRec = _socket.Receive(readBuffer);
         return Encoding.UTF8.GetString(readBuffer, 0, bytesRec);

         if (readBuffer[0] != OK)
                {
                    MessageBox.Show(goodsInfo[0]);
                    break;//如果失敗則停止繼續發送
                }

總結:1、與服務器連接最好是同步連接的方式,這樣可以等待服務器的反應。當網絡狀態不好時,尤其重要。

            2、每次發送一定要等待服務器的返回結果,不能看客戶端的表象,因爲有時候是假象。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章