C# socket客户端接收不到服务端返回的数据

时间:2022-08-28 22:49:40
本人不太懂网络通信,socket新手。现在的问题是,同样的代码在pc端能正常运行,且能接收到服务端的数据,但是在采集器(WinCE5.0)上运行就发生卡死现象,且收不到服务端返回的数据,一直找不到问题的原因,向大家求助!代码如下:

Socket类代码:

namespace bnSocket
{
    class bnSocket
    {
        private Socket m_socket;
        private int m_nReturn;

        public bnSocket()
        {
        }

        /// <summary>
        /// 发送数据到服务器
        /// </summary>
        /// <param name="sSend">发送内容</param>
        /// <returns>返回异常消息</returns>
        public string SendData(string sSend)
        {
            string msg = "";
            try
            {
                if (m_nReturn != -1)
                {
                    msg = "ABC网络异常,无法请求服务器!";  //是否已经连接到服务器
                }

                byte[] byteMesage = new byte[sSend.Length];
                byteMesage = Encoding.GetEncoding("gb2312").GetBytes(sSend);// .Default.GetBytes(sSend);
                m_socket.Send(byteMesage);
            }
            catch
            {
                msg = "ABC网络异常断开连接";
            }

            return msg;
        }

        /// <summary>
        /// 从服务器获取信息
        /// </summary>
        /// <returns>服务器返回信息给客户端</returns>
        public string ReceiveMsg()
        {
            string msg = "";
            try
            {
                if (m_nReturn != -1)
                {
                    msg = "ABC网络异常,无法请求服务器!";  //是否已经连接到服务器
                }

                while (true)
                {
                    byte[] byRead = new byte[1024];
                    m_socket.Receive(byRead);
                    msg = Encoding.GetEncoding("gb2312").GetString(byRead, 0, byRead.Length);
                    Thread.Sleep(500);

                    if (byRead.Length == 0)
                    {
                        break;
                    }
                }
                
            }
            catch(Exception ex)
            {
                msg = "ABC网络异常断开连接";
            }
            return msg;
        }

        /// <summary>
        /// 连接服务器
        /// </summary>
        /// <param name="sServerIp">服务器IP地址</param>
        /// <param name="nPort">端口号</param>
        /// <returns>-1=>成功; -2=>IP无效; -3=>连接服务器失败,请查看服务器是否已经运行或者网络连接是否正常</returns>
        public int ConnectServer(string sServerIp, int nPort)
        {
            IPAddress serverIp;
            try
            {
                serverIp = IPAddress.Parse(sServerIp);
            }
            catch
            {
                //连接失败,IP无效
                m_nReturn = -2;
                return -2;
            }

            try
            {
                IPEndPoint iep = new IPEndPoint(serverIp, nPort);
                m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                m_socket.Connect(iep);
                m_nReturn = -1;
                return -1; //连接成功

            }
            catch
            {
                //连接服务器失败,请查看服务器是否已经运行或者网络连接是否正常
                m_nReturn = -3;
                return -3;
            }
        }

        /// <summary>
        /// 获取本机IP地址
        /// </summary>
        public string GetIPAddress()
        {
            IPHostEntry ipAddress = Dns.GetHostByName(Dns.GetHostName());
            return ipAddress.AddressList[0].ToString();
        }

        /// <summary>
        /// 断开与服务器的连接
        /// </summary>
        public int EndConnectServer()
        {
            if (m_nReturn == -1)
            {
                m_socket.Shutdown(SocketShutdown.Both);
                m_socket.Close();
                m_nReturn = -100;
            }
            return m_nReturn;
        }

        /// <summary>
        /// 获得连接状态
        /// </summary>
        /// <returns></returns>
        public int GetConnectState()
        {
            return m_nReturn;
        }
    }
}


4 个解决方案

#1


客户端窗体部分代码:

namespace PDA
{
    public partial class frm_Main : Form
    {
        public frm_Main()
        {
            InitializeComponent();
        }

        //定义启动网络连接的定时器
        System.Threading.Timer startNetTimer;

        //定义定时器
        System.Threading.Timer timer;

        System.Threading.Timer getSNTimer;

        System.Threading.Timer getNetStatus;

        System.Threading.Timer receiveMsgTimer;
        Thread receiveMsg;

        //服务器连接状态标志
        private int m_ConnectionState = 0;
        private bnSocket.bnSocket mySocket = new bnSocket.bnSocket();

        //(2) 全局变量
        //(2.1) 记录上次操作模块
        private string m_sLastModule = "";
        //(2.2) 主程序全路径 + 名称
        private static string m_sFullAppName = Assembly.GetExecutingAssembly().GetName().CodeBase;
        //(2.3) 主程序全路径
        private static string m_sFullAppPath = Path.GetDirectoryName(m_sFullAppName);   //PAD
        //(2.3) 基础数据库文件连接对像
        private string m_TempSaveFile = m_sFullAppPath + @"\_Save.txt";
        //(2.8) 网络连接IP地址
        private string m_sIP = "";
        //(2.9) 网络连接端口号
        private int m_nPort = 0;
        
        #region 初始
        private void frm_Main_Load(object sender, EventArgs e)
        {
            //设置窗体位于程序最顶端
            this.TopMost = true;
            string sLines = "";
            string[] strArr;
            string filename = m_sFullAppPath + @"\config.ini";
            StreamReader sr = new StreamReader(filename, Encoding.Default);
            while ((sLines = sr.ReadLine()) != null)
            {
                strArr = sLines.Split('|');
                m_sIP = strArr[0].ToString().Trim();
                m_nPort = Convert.ToInt32(strArr[1].ToString().Trim());
            }
            sr.Close();

            //读取原密码
            string pwdFileName = m_sFullAppPath + @"\gzbonny.bin";
            if (File.Exists(pwdFileName))
            {
                string sPwd = Commond.ReadFile(pwdFileName);
                m_sOldPwd = Commond.DecryptString(sPwd);
            }

            this.lblStatus.Text = "正在连接网络...";
            //启用定时器执行服务器连接
            object obj = (object)7;
            startNetTimer = new System.Threading.Timer(new TimerCallback(Connect2Server), obj, 1000, 2000);
            
         }

        /// <summary>
        /// 连接服务器
        /// </summary>
        private void Connect2Server(object obj)
        {
            if (startNetTimer != null)
            {
                startNetTimer.Dispose();
                startNetTimer = null;
            }
            m_ConnectionState = mySocket.ConnectServer(m_sIP, m_nPort);
            this.Invoke(new EventHandler(delegate
            {
                switch (m_ConnectionState)
                {
                    case -1:
                        this.lblStatus.Text = "已连接";
                        this.lblStatus2.Text = "已连接";
                        string ipAddress = mySocket.GetIPAddress();
                        //向服务端发送信息
                        string msg = "The client " + ipAddress + " online!";
                        mySocket.SendData(msg);
                        //开启定时器,启用接收数据的线程
                        receiveMsgTimer = new System.Threading.Timer(new TimerCallback(StartThread), obj, 1000, 1000);
                        break;
                    case -2:
                        this.lblStatus.Text = "IP无效";
                        this.lblStatus2.Text = "IP无效";
                        break;
                    case -3:
                        this.lblStatus.Text = "网络异常连接失败";
                        this.lblStatus2.Text = "网络异常连接失败";
                        break;
                    case -100:
                        this.lblStatus.Text = "网络异常断开连接";
                        this.lblStatus2.Text = "网络异常断开连接";
                        break;
                    default:
                        this.lblStatus.Text = "网络异常,请查看无线网络";
                        this.lblStatus2.Text = "网络异常,请查看无线网络";
                        break;
                }
            }));
            this.BeginTheTimer();

        }

        //启动定时器
        private void BeginTheTimer()
        {
            //这里只是要一个object类型数据,用它做为下面Timer的参数之一,没有其它意思
            object myobject = (object)7;

            //暂时设定为2秒钟启动一次!
            timer = new System.Threading.Timer(new System.Threading.TimerCallback(GetState), myobject, 3000, 5000);

        }

        /// <summary>
        /// 获取连接状态
        /// </summary>
        private void GetState(object myobject)
        {
            string msg = mySocket.SendData("C2S");
            if (msg.StartsWith("ABC网络异常"))
            {
                timer.Dispose();
                m_ConnectionState = -3;

                object obj = (object)7;
                this.Connect2Server(obj);
            }
        }
        #endregion
        /// <summary>
        /// 执行线程
        /// </summary>
        /// <param name="obj"></param>
        private void StartThread(object obj)
        {
            if (receiveMsgTimer != null)
            {
                receiveMsgTimer.Dispose();
                receiveMsgTimer = null;
            }
            //开启线程,执行GetMsg()接收服务端消息
            receiveMsg = new Thread(new ThreadStart(GetMsg));
            receiveMsg.IsBackground = true;
            receiveMsg.Start();
        }

        #region 发送
        private void Send()
        {
            if (!ValiText())
                return;
            string InitMsg = this.txtReceive.Text;
            string sendMsg = m_operateParam + InitMsg + ":" + this.txtSendMsg.Text;
            string returnMsg = mySocket.SendData(sendMsg);
            if (returnMsg != "")
            {
                this.txtReceive.Text = returnMsg.Substring(3);
            }
            //this.txtReceive.Text = returnMsg;
            this.txtSendMsg.Text = "";
            this.txtSendMsg.Focus();
        }
        #endregion

        #region 接收信息
        private void GetMsg()
        {
            this.Invoke(new EventHandler(delegate {
                this.txtReceive.Text = mySocket.ReceiveMsg();
            })); 
        } 
        #endregion
    }
}

#2


和环境相关,在模拟器上调试Socket时也是只能单方向的 

#3


引用 2 楼 wuyq11 的回复:
和环境相关,在模拟器上调试Socket时也是只能单方向的

与环境相关的话问题是不是很不好解决?

#4


    Thread.Sleep(500);

                    if (byRead.Length == 0)
                    {
                        break;
                    }

会不会是sleep 500ms,一直有数据,就在循环里出不来了?

#1


客户端窗体部分代码:

namespace PDA
{
    public partial class frm_Main : Form
    {
        public frm_Main()
        {
            InitializeComponent();
        }

        //定义启动网络连接的定时器
        System.Threading.Timer startNetTimer;

        //定义定时器
        System.Threading.Timer timer;

        System.Threading.Timer getSNTimer;

        System.Threading.Timer getNetStatus;

        System.Threading.Timer receiveMsgTimer;
        Thread receiveMsg;

        //服务器连接状态标志
        private int m_ConnectionState = 0;
        private bnSocket.bnSocket mySocket = new bnSocket.bnSocket();

        //(2) 全局变量
        //(2.1) 记录上次操作模块
        private string m_sLastModule = "";
        //(2.2) 主程序全路径 + 名称
        private static string m_sFullAppName = Assembly.GetExecutingAssembly().GetName().CodeBase;
        //(2.3) 主程序全路径
        private static string m_sFullAppPath = Path.GetDirectoryName(m_sFullAppName);   //PAD
        //(2.3) 基础数据库文件连接对像
        private string m_TempSaveFile = m_sFullAppPath + @"\_Save.txt";
        //(2.8) 网络连接IP地址
        private string m_sIP = "";
        //(2.9) 网络连接端口号
        private int m_nPort = 0;
        
        #region 初始
        private void frm_Main_Load(object sender, EventArgs e)
        {
            //设置窗体位于程序最顶端
            this.TopMost = true;
            string sLines = "";
            string[] strArr;
            string filename = m_sFullAppPath + @"\config.ini";
            StreamReader sr = new StreamReader(filename, Encoding.Default);
            while ((sLines = sr.ReadLine()) != null)
            {
                strArr = sLines.Split('|');
                m_sIP = strArr[0].ToString().Trim();
                m_nPort = Convert.ToInt32(strArr[1].ToString().Trim());
            }
            sr.Close();

            //读取原密码
            string pwdFileName = m_sFullAppPath + @"\gzbonny.bin";
            if (File.Exists(pwdFileName))
            {
                string sPwd = Commond.ReadFile(pwdFileName);
                m_sOldPwd = Commond.DecryptString(sPwd);
            }

            this.lblStatus.Text = "正在连接网络...";
            //启用定时器执行服务器连接
            object obj = (object)7;
            startNetTimer = new System.Threading.Timer(new TimerCallback(Connect2Server), obj, 1000, 2000);
            
         }

        /// <summary>
        /// 连接服务器
        /// </summary>
        private void Connect2Server(object obj)
        {
            if (startNetTimer != null)
            {
                startNetTimer.Dispose();
                startNetTimer = null;
            }
            m_ConnectionState = mySocket.ConnectServer(m_sIP, m_nPort);
            this.Invoke(new EventHandler(delegate
            {
                switch (m_ConnectionState)
                {
                    case -1:
                        this.lblStatus.Text = "已连接";
                        this.lblStatus2.Text = "已连接";
                        string ipAddress = mySocket.GetIPAddress();
                        //向服务端发送信息
                        string msg = "The client " + ipAddress + " online!";
                        mySocket.SendData(msg);
                        //开启定时器,启用接收数据的线程
                        receiveMsgTimer = new System.Threading.Timer(new TimerCallback(StartThread), obj, 1000, 1000);
                        break;
                    case -2:
                        this.lblStatus.Text = "IP无效";
                        this.lblStatus2.Text = "IP无效";
                        break;
                    case -3:
                        this.lblStatus.Text = "网络异常连接失败";
                        this.lblStatus2.Text = "网络异常连接失败";
                        break;
                    case -100:
                        this.lblStatus.Text = "网络异常断开连接";
                        this.lblStatus2.Text = "网络异常断开连接";
                        break;
                    default:
                        this.lblStatus.Text = "网络异常,请查看无线网络";
                        this.lblStatus2.Text = "网络异常,请查看无线网络";
                        break;
                }
            }));
            this.BeginTheTimer();

        }

        //启动定时器
        private void BeginTheTimer()
        {
            //这里只是要一个object类型数据,用它做为下面Timer的参数之一,没有其它意思
            object myobject = (object)7;

            //暂时设定为2秒钟启动一次!
            timer = new System.Threading.Timer(new System.Threading.TimerCallback(GetState), myobject, 3000, 5000);

        }

        /// <summary>
        /// 获取连接状态
        /// </summary>
        private void GetState(object myobject)
        {
            string msg = mySocket.SendData("C2S");
            if (msg.StartsWith("ABC网络异常"))
            {
                timer.Dispose();
                m_ConnectionState = -3;

                object obj = (object)7;
                this.Connect2Server(obj);
            }
        }
        #endregion
        /// <summary>
        /// 执行线程
        /// </summary>
        /// <param name="obj"></param>
        private void StartThread(object obj)
        {
            if (receiveMsgTimer != null)
            {
                receiveMsgTimer.Dispose();
                receiveMsgTimer = null;
            }
            //开启线程,执行GetMsg()接收服务端消息
            receiveMsg = new Thread(new ThreadStart(GetMsg));
            receiveMsg.IsBackground = true;
            receiveMsg.Start();
        }

        #region 发送
        private void Send()
        {
            if (!ValiText())
                return;
            string InitMsg = this.txtReceive.Text;
            string sendMsg = m_operateParam + InitMsg + ":" + this.txtSendMsg.Text;
            string returnMsg = mySocket.SendData(sendMsg);
            if (returnMsg != "")
            {
                this.txtReceive.Text = returnMsg.Substring(3);
            }
            //this.txtReceive.Text = returnMsg;
            this.txtSendMsg.Text = "";
            this.txtSendMsg.Focus();
        }
        #endregion

        #region 接收信息
        private void GetMsg()
        {
            this.Invoke(new EventHandler(delegate {
                this.txtReceive.Text = mySocket.ReceiveMsg();
            })); 
        } 
        #endregion
    }
}

#2


和环境相关,在模拟器上调试Socket时也是只能单方向的 

#3


引用 2 楼 wuyq11 的回复:
和环境相关,在模拟器上调试Socket时也是只能单方向的

与环境相关的话问题是不是很不好解决?

#4


    Thread.Sleep(500);

                    if (byRead.Length == 0)
                    {
                        break;
                    }

会不会是sleep 500ms,一直有数据,就在循环里出不来了?