商定协议如下:
客户端发送单个字符'p’,服务器接收到'p'后,将'p'返回给客户端,然后客户端发送4个字节的参数码给
服务器,服务器接收到参数后返回字符'b',客户端发送结束字符'f'给服务器,服务器接收到'f',回发字
符'f'给客户端,通信结束;现在出现问题是:服务器三次回发给客户端的字符'p','b','f',但客户端接收到得字符出错了,却是三个'p'。客户端网络实现代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;using System.Net;
using System.Net.Sockets;
using System.Threading;
using Network.DataStruct;
namespace Network {
    class TcpClient {
        private Socket _Socket = null;
        private IPEndPoint ipEndPoint = null;        public string retMsg = null; //接收回传数据
        public byte[] buffer = new byte[4]; //发送与接收的缓冲区
        /*
         * 构造函数
         */ 
        public TcpClient(IPContext _ipContext) {
            InitSocket(_ipContext.ip, _ipContext.port);
        }        public TcpClient(IPAddress _ip,int _port) {
            InitSocket(_ip, _port);
        }        /*
         * 初始化Socket
         */ 
        private void InitSocket(IPAddress _ip, int _port) {
            ipEndPoint = new IPEndPoint(_ip, _port);
            _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _Socket.SendTimeout = 2000;
            _Socket.ReceiveTimeout = 3000;
            _Socket.ReceiveBufferSize = 1;
        }
        /*
         * 连接初始化后的_Socket
         * 连接成功返回true
         * 连接失败返回false
         */ 
        public bool TcpConnect(){
            try {
                _Socket.Connect(ipEndPoint);
            } catch(SocketException se) {
                Console.WriteLine(" SocketException : {0}", se.ToString());
                return false;
            } catch (Exception e) {
                Console.WriteLine(e.ToString());
                return false;
            }            return true;
        }        /*
         * 发送msg字符串到_Socket连接的端点
         * 
         */ 
        public bool TcpSend(string msg) {
            do {
                try {
                    if (_Socket.Poll(50, SelectMode.SelectWrite)) { 
                        /*
                         *检测网络是否能够被写(即能否发送)
                         *正确直行Send函数
                         *不正确程序睡眠100ms,继续检测
                         *该函数陷入不会死循环
                         */
                        int bytesSent = _Socket.Send(Encoding.ASCII.GetBytes(msg));
                        Console.WriteLine(" TcpSend --> Send Message : {0}", msg.ToString());
                        if (bytesSent > 0) break;
                    }
                } catch (Exception e) {
                    Console.WriteLine(" TcpSend --> Network connection is break ,{0}",e.ToString());
                    return false;
                }
                Thread.Sleep(100);
            } while (true);
            return true;
        }        public bool TcpSend(byte[] msg) {
            do {
                try {
                    if (_Socket.Poll(50, SelectMode.SelectWrite)) {
                        /*
                         *检测网络是否能够被写(即能否发送)
                         *正确直行Send函数
                         *不正确程序睡眠100ms,继续检测
                         *该函数陷入不会死循环
                         */
                        int bytesSent = _Socket.Send(msg);
                        for(int i = 0;i < msg.Length;i ++)
                            Console.WriteLine(" TcpSend --> Send Message : "+ msg[i]);
                        if (bytesSent > 0) break;
                    }
                } catch (Exception e) {
                    Console.WriteLine(" TcpSend --> Network connection is break ,{0}", e.ToString());
                    return false;
                }
                Thread.Sleep(100);
            } while (true);
            return true;
        }        public bool TcpSend(byte _msg) {
            byte[] msg = new byte[1];
            msg[0] = _msg;
            do {
                try {
                    if (_Socket.Poll(50, SelectMode.SelectWrite)) {
                        /*
                         *检测网络是否能够被写(即能否发送)
                         *正确直行Send函数
                         *不正确程序睡眠100ms,继续检测
                         *该函数陷入不会死循环
                         */
                        int bytesSent = _Socket.Send(msg);
                        for (int i = 0; i < msg.Length; i++)
                            Console.WriteLine(" TcpSend --> Send Message : " + msg[i]);
                        if (bytesSent > 0) break;
                    }
                } catch (Exception e) {
                    Console.WriteLine(" TcpSend --> Network connection is break ,{0}", e.ToString());
                    return false;
                }
                Thread.Sleep(100);
            } while (true);
            return true;
        }        /*
         * 从已经初始化完成的_Socket中,获取已接收到得字符串
         */ 
        public bool TcpReceive() {
            int TimeOut = 0;
            do {
                Thread.Sleep(100);
                try {
                    if (_Socket.Poll(50, SelectMode.SelectRead)) {
                        /*
                         *检测网络是否能够被写(即能否发送)
                         *正确直行Send函数
                         *不正确程序睡眠100ms,继续检测
                         *该函数陷入死循环可能性极小,情况如下:
                         *在100ms内,信号机回传了
                         */
                        int bytesRecv = _Socket.Receive(buffer);
                        if (bytesRecv > 0) {
                            retMsg = Encoding.ASCII.GetString(buffer);
                            dtLog.Log(" TcpReceive --> Recv Message :" + (_Socket.RemoteEndPoint as IPEndPoint).Address.ToString() + buffer[0] +" len : "+ bytesRecv.ToString());
                            break;
                        }
                    }
                } catch (Exception e) {
                    Console.WriteLine(" TcpReceive --> Network connection is break ,{0}",e.ToString());
                    return false;
                }
                if (++TimeOut >= 19) return false; //超时设置2秒
            } while (true);
            return true;
        }        public bool TcpEnd() {
            try {
                _Socket.Shutdown(SocketShutdown.Both);
                _Socket.Close();
            }catch(Exception e){
                Console.WriteLine(" TcpEnd --> Network connection is break ,{0}",e.ToString());
                return false;
            }
            return true;
        }        public bool TcpTestConnect() {
            return _Socket.Connected;
        }    }
}逻辑代码:private void ParameterCommand(TcpClient _TcpClient, IPContext _ipContext) {
            byte[] data = { 0x0D, 0x0B, 0x1B, 0x0B, 0x02, 0x23};
            //string data = "141127110235";
            int i = 0;
            _TcpClient.TcpConnect();
            
            _TcpClient.TcpSend("p");
            _TcpClient.TcpReceive();
            if (_TcpClient.buffer[0].Equals(0x70)) { //接收到返回的‘p’
                _TcpClient.buffer[0] = 0xff;
                _TcpClient.TcpSend(data);
                _TcpClient.TcpReceive();
                if (_TcpClient.buffer[0].Equals(0x62)) { //接收到返回的‘b’
                    Console.WriteLine("buf[1] : " + _TcpClient.buffer[2]);
                    _TcpClient.buffer[0] = 0xff;
                    _TcpClient.TcpSend("f");
                    _TcpClient.TcpReceive();
                    if (_TcpClient.buffer[0].Equals(0x66)) { //接收到返回的‘f’
                        Console.WriteLine("buf[2] : " + _TcpClient.buffer[3]);
                        Console.WriteLine("通信结束:" + _TcpClient.buffer[0]);
                        //return;
                    }
                } else {
                    Console.WriteLine("没有等待返回的'b',返回值为:" + _TcpClient.buffer[0]);
                }
            } else {
                Console.WriteLine("没有等待返回的'p',返回值为:" + _TcpClient.buffer[0]);
            }      
 
        }
我猜测是不是TCP的缓冲区没有改变,一直保存的是第一次接收的字符'p'!!求各位给点建议啊!谢谢

解决方案 »

  1.   

    有可能是这个原因啊,我客户端的自己定义的缓冲区已经清空了,而且重新复制为0xff,但是接受到的值还是一直都是‘p’,猜测原因是:TCP socket的缓冲区中一直是‘p’,怎么清空socket的缓冲区啊?
      

  2.   

    每次客户端接收的完之后,记得立即清空缓存。
     _TcpClient.TcpSend("p");
                _TcpClient.TcpReceive();
                if (_TcpClient.buffer[0].Equals(0x70)) { //接收到返回的‘p’
                    _TcpClient.buffer[0] = 0xff;
                    _TcpClient.TcpSend(data);
                    
                  //这里写清空缓存
                    _TcpClient.TcpReceive();
                    if (_TcpClient.buffer[0].Equals(0x62)) { //接收到返回的‘b’
                        Console.WriteLine("buf[1] : " + _TcpClient.buffer[2]);
                        _TcpClient.buffer[0] = 0xff;
                        _TcpClient.TcpSend("f");
             //这里写清空缓存
                        _TcpClient.TcpReceive();
                        if (_TcpClient.buffer[0].Equals(0x66)) { //接收到返回的‘f’
                            Console.WriteLine("buf[2] : " + _TcpClient.buffer[3]);
                            Console.WriteLine("通信结束:" + _TcpClient.buffer[0]);
             //这里写清空缓存
                            //return;
      

  3.   

    问题解决了,因为服务器的数据没有到达,客户端就去接收了。因为协议的各个步骤我只是去send 与recv都只有一次,所以读取得都是原来的值,将程序改成如下:private void ParameterCommand(TcpClient _TcpClient, IPContext _ipContext) {
                byte[] data = { 0x0D, 0x0B, 0x1B, 0x0B, 0x02, 0x23};
                //string data = "141127110235";
                int step = 0;
                //int i = 0;
                _TcpClient.TcpConnect();            do {
                    if (step == 0) { //发送 p 命令
                        _TcpClient.TcpSend("p");
                        _TcpClient.TcpReceive();
                        if (_TcpClient.buffer[0].Equals(0x70)) step++;
                    } else if (step == 1) { //发送数据
                        _TcpClient.TcpSend(data);
                        _TcpClient.TcpReceive();
                        if (_TcpClient.buffer[0].Equals(0x62)) step++;
                    } else if (step == 2) { //发送结束字符
                        _TcpClient.TcpSend("f");
                        _TcpClient.TcpReceive();
                        if (_TcpClient.buffer[0].Equals(0x66)) break;
                    } 
                    Thread.Sleep(1000);
                } while (true);
                
            }
      

  4.   

    但是现在出现了该问题留下的后遗症,能很快接收'p',但是接收结束'b'和接收字符'f'的时候,速度非常慢啊
    要接收400次左右才能收到字符'b',‘f’,求解释啊!!!?
      

  5.   


    请问清空缓存,缓存是指自己定义的接收缓存还是系统定义Socket的接收缓存?