我做了服务器端与客户端程序,服务器端接收客户端程序发送过来的数据后查询数据库,然后把查询结果返回给客户端。每次发送的字符不会超过100个。服务器端放在WIN SERVER 2003上。如果客户端不关闭数据能正常接发,第一次关闭客户端后,重启客户端仍然能够正常通信,第二次关闭后,再重启,提示信息两端已经连接,但是就是不能通信,这个时候把服务器端程序重启后工作正常。谁能告诉我解决的办法与原理?每次关闭客户端程序之前我都对连接套接字进行关闭操作。另外需要说明的是:如果服务器端是在单核CPU、OS是XP上,则不会出现上面的问题,如果服务器端装在双核CPU,也会出现上面的问题。

解决方案 »

  1.   

    你可以尝试OPEN连接,然后随便做个SQL指令,看不能不执行.
    如果可以,则连接被关闭了,检查代码.不行的话,连接没了...重连吧
      

  2.   

    以下是服务器端程序:class DataReadWrite
        {
            public TcpClient client;
            public NetworkStream ns;
            public byte[] read;
            public byte[] write;
            public DataReadWrite(TcpClient client)
            {
                this.client = client;
                ns = client.GetStream();
                read = new byte[client.ReceiveBufferSize];
                write=new byte[client.SendBufferSize];
            }
            public void InitReadArray()
            { 
                read=new byte[client.ReceiveBufferSize];
            }
            public void InitWriteArray()
            { 
                write=new byte[client.SendBufferSize];
            }
        }class ServerPrag
    {        private bool isExit = false;        
            
            TcpListener listener;
            private ManualResetEvent allDone = new ManualResetEvent(false);
            public Thread myThread;
            
            private ListBox listbox;
            private Queue queueRevStr = new Queue();
            
            public ServerPrag()
            {   
                myThread = new Thread(new ThreadStart(AcceptConnection));
                myThread.Start();
            }       
        
            private void AcceptConnection()
            {
                IPAddress[] ip = Dns.GetHostAddresses(Dns.GetHostName());// Dns.GetHostEntry("localhost").AddressList[0];
                IPEndPoint ipendPoint = new IPEndPoint(ip[1], int.Parse(ManangeAppConfig.ReadConfig("Port")));
                listener = new TcpListener(ipendPoint);            
                listener.Start();
                while (isExit == false)
                {
                    try
                    {
                        allDone.Reset();
                        AsyncCallback callback = new AsyncCallback(AcceptTcpClientCallBack);
                        listener.BeginAcceptTcpClient(callback, listener);
                        allDone.WaitOne();
                    }
                    catch (Exception e)
                    {
                        queueRevStr.Enqueue("网络连接出现异常:"+e.Message);
                        break;
                    }
                }
            }
            private void AcceptTcpClientCallBack(IAsyncResult iar)
            {
                try
                {
                    allDone.Set();
                    TcpListener mylistener = (TcpListener)iar.AsyncState;
                    TcpClient client = mylistener.EndAcceptTcpClient(iar);
                    
                    queueRevStr.Enqueue("已接受连接……");
                    DataReadWrite datareadwrite = new DataReadWrite(client);
                    if (datareadwrite.ns.CanRead)
                    {
                        datareadwrite.ns.BeginRead(datareadwrite.read, 0, datareadwrite.read.Length, ReadCallBack, datareadwrite);
                        queueRevStr.Enqueue("开始接收数据……");
                    }
                    else
                        queueRevStr.Enqueue("客户端程序已经关闭");
                    allDone.WaitOne();
                }
                catch (Exception e)
                {
                    queueRevStr.Enqueue("网络连接回调出现异常:" + e.Message);
                    return ;
                }
            }        static string lsReceivedStr="";
            private void ReadCallBack(IAsyncResult iar)
            {            
                DataReadWrite datareadwrite = (DataReadWrite)iar.AsyncState;
                allDone.Set();
                try
                {
                    int recv = 0;
                    lsReceivedStr = "";
                    recv = datareadwrite.ns.EndRead(iar);
                    if (recv > 0)
                    {
                        queueRevStr.Enqueue("数据读取完成!");
                        allDone.Reset();
                        lsReceivedStr = Encoding.UTF8.GetString(datareadwrite.read, 0, recv);
                        queueRevStr.Enqueue("开始处理数据……");
                        queueRevStr.Enqueue(lsReceivedStr);
                        if (isExit == false)
                        {
                            datareadwrite.InitReadArray();
                            datareadwrite.ns.BeginRead(datareadwrite.read, 0, datareadwrite.read.Length, ReadCallBack, datareadwrite);
                        }
                        allDone.WaitOne();                    
                    }
                    else
                    {
                        datareadwrite.client.Close();
                        datareadwrite.ns.Close();                    
                        queueRevStr.Enqueue("远程终端关闭!");
                    }
                }
                catch (Exception e)
                {
                    getValFromHash(htclientlist, tempTID);
                    datareadwrite.client.Close();
                    datareadwrite.ns.Dispose();
                    datareadwrite.ns.Close();
                    queueRevStr.Enqueue("远程终端异常,连接关闭!"+e.Message);
                    
                }            
            }
            private void SendString(DataReadWrite datareadwrite, string str)
            {
                try
                {
                    if (datareadwrite.ns!=null&&datareadwrite.client != null && datareadwrite.client.Client.Connected)
                    {
                        datareadwrite.write = Encoding.ASCII.GetBytes(str + "\r\n");
                        datareadwrite.ns.BeginWrite(datareadwrite.write, 0, datareadwrite.write.Length, new AsyncCallback(SendCallBack), datareadwrite);
                        datareadwrite.ns.Flush();
                        queueRevStr.Enqueue("开始回复数据……");
                    }
                    else
                    {
                        //datareadwrite.ns.Close();
                        //datareadwrite.client.Client.Disconnect(false);
                        //datareadwrite.client.Close();
                        queueRevStr.Enqueue("远程终端关闭,无法发送数据");
                    }
                }
                catch (Exception e)
                {
                    datareadwrite.ns.Close();
                    datareadwrite.client.Client.Disconnect(false);
                    datareadwrite.client.Close();
                    queueRevStr.Enqueue("远程终端关闭,无法发送数据");
                    MessageBox.Show(e.Message+e.StackTrace, "SendString:"+e.Source);
                }
            }        private void SendCallBack(IAsyncResult iar)
            {
                DataReadWrite datareadwrite = (DataReadWrite)iar.AsyncState;            try
                {
                    datareadwrite.ns.EndWrite(iar);
                    //datareadwrite.client.Client.Shutdown(SocketShutdown.Both);
                    queueRevStr.Enqueue("回复数据成功!");
                    queueRevStr.Enqueue("============"+DateTime.Now.ToString()+"===============");
                }
                catch (Exception e)
                {
                    queueRevStr.Enqueue("回复数据回调出现异常!"+e.Message);
                }
            }
            public void getListBox(ListBox lb)
            {
                listbox=lb;
            }
            public void insertListBox()
            {
                if (listbox.Items.Count > 1000)
                    listbox.Items.Clear();
                if (queueRevStr.Count>0)
                {
                    listbox.Items.Add(queueRevStr.Dequeue().ToString());                
                }
            }
        }
      

  3.   

    以下是客户端程序:
    class DataRead
        {
            public NetworkStream ns;
            public byte[] msg;
            public DataRead(NetworkStream ns, int buffersize)
            {
                this.ns = ns;
                msg = new byte[buffersize];
            }
        }
        public delegate void CloseParentWin();
        public partial class InfoForm : Form
        {
            private bool isLive = false;
            private TcpClient client;
            private NetworkStream ns;
            private ManualResetEvent allDone = new ManualResetEvent(false);
            
            
            private delegate void SetRichTextBoxReceiveCallBack(string str);
            private SetRichTextBoxReceiveCallBack setRichTextBoxReceiveCallBack;
            
            eventReadFromT evReadFromT = new eventReadFromT();
            //定义两个队列,第一个队列放置从终端收到的数据,第二个队列放置从中心服务器收到的发往终端的数据       
            private Queue<string> queueFromT=new Queue<string>();
            private Queue<string> queueToT = new Queue<string>();
            private Queue<string> queueRevStr = new Queue<string>();
            private Queue<string> queueRevStrToT=new Queue<string>();
            //CommLib CLib = new CommLib();
            Security rijndael = new Security();
            //定义一个静态变量是进行计时,如果空闲时间达到60S,中断网络连接
            private static int FreeTimes=60;
            private static int ConnectTryNum = 0;
            private static float psfX = 0,psfY=0;
            
    //委托调用该方法:如果发送数据队列中有数据,并且已经连接到服务器,则发送数据,否则先连接服务器再发送数据
            private void readFromQueue(object sender,EventArgs e)
            {
                string lstemp = "";
                if (queueFromT.Count > 0)
                {
                    if (client == null || !client.Connected)
                    {
                        if (ConnectTryNum <3)
                        {
                            ConnectTryNum++;
                            SetListBox("正在进行第" + ConnectTryNum.ToString() + "次(共尝试连接3次)尝试连接到中心服务器……");
                            ConnectServer();                        
                        }
                        else
                        {
                            timer1.Enabled = false;
                            timerSend.Enabled = false;
                        }
                    }
                    else
                    {
                        lstemp += queueFromT.Dequeue().ToString();
                        SendData(lstemp);
                    }
                }
            }        public InfoForm()
            {            
                InitializeComponent();
                Application.EnableVisualStyles();
                Application.DoEvents();
                
                setRichTextBoxReceiveCallBack = new SetRichTextBoxReceiveCallBack(SetRichTextBoxReceive);            
                evReadFromT.rtspEvent +=new delegateReadTSerialPort(readFromQueue);            
            }  //通过一个计时器定时把取得的数据放到一个发送队列中
            private void timer1_Tick(object sender, EventArgs e)
            {
                StringBuilder s = new StringBuilder(120);//申明一个StringBuilder对象
                int i = GetDateFromEar(s);               //从串口读取一个数据
                //i = 1;
                string temp = s.ToString();//"0,0,123456800,111,37.25,0,cd3f3e0f000104e0";//
                if (i > 0)
                {                
                    queueFromT.Enqueue(temp);               
                }
                else
                {                MessageBox.Show("读入的数据有误:" + temp, "警告");
                }
                else
                {
                    FreeTimes--;
                    if (FreeTimes == 0&&client!=null&&client.Client.Connected)
                    {
                        client.Close();
                        client.Client.Close();
                    }
                }
            }        private void ConnectServer()
            {
                client = new TcpClient(AddressFamily.InterNetwork);
                IPAddress IP = IPAddress.Parse(ManangeAppConfig.ReadConfig("IP"));
                AsyncCallback connectCallBack = new AsyncCallback(ConnectCallBack);
                allDone.Reset();
                client.BeginConnect(IP, int.Parse(ManangeAppConfig.ReadConfig("Port")), connectCallBack, client);
                queueRevStr.Enqueue("开始连接服务器……");
                allDone.WaitOne();
            }        private void ConnectCallBack(IAsyncResult iar)
            {
                allDone.Set();
                try
                {
                    client = (TcpClient)iar.AsyncState;
                    client.EndConnect(iar);
                    if (client.Connected)
                    {
                        queueRevStr.Enqueue("连接服务器成功!");
                        listBoxStatus.Invoke(setlistboxcallback, string.Format("与服务器{0}连接成功", client.Client.RemoteEndPoint));
                        ConnectTryNum = 0;
                        ns = client.GetStream();
                        DataRead dataRead = new DataRead(ns, client.ReceiveBufferSize);
                        ns.BeginRead(dataRead.msg, 0, dataRead.msg.Length, ReadCallBack, dataRead);
                        queueRevStr.Enqueue("开始从中心服务器读取数据……");
                    }
                    else
                        queueRevStr.Enqueue("无法连接到中心服务器!");
                }
                catch (Exception e)
                {
                    listBoxStatus.Invoke(setlistboxcallback, "ConnectCallBack(连接中心服务器异常):"+e.Message);
                    return;
                }
            }
            private void ReadCallBack(IAsyncResult iar)
            {
                try
                {
                    DataRead dataRead = (DataRead)iar.AsyncState;
                    int recv = dataRead.ns.EndRead(iar);
                    string strRecvFromServer=Encoding.UTF8.GetString(dataRead.msg, 0, recv);
                    queueRevStr.Enqueue("读取返回数据:" + strRecvFromServer);
    //如果收到回复数据,则在窗口中显示收到的数据,然后关闭连接                
                    if (strRecvFromServer.Trim().Length > 0)
                    {
                        richTextBoxRecv.Invoke(setRichTextBoxReceiveCallBack, strRecvFromServer);
                        if (isLive == false && ns != null)
                        {
                            dataRead = new DataRead(ns, client.ReceiveBufferSize);
                            ns.BeginRead(dataRead.msg, 0, dataRead.msg.Length, ReadCallBack, dataRead);
                        }
                    }
                    client.Client.Disconnect(true);
                    client.Client.Close();
                    client.Close();
                }
                catch (Exception e)
                {
                    client.Client.Disconnect(true);
                    client.Client.Close();
                    client.Close();  
                }
            }
            private void SendData(string str)
            {
                try
                {
                    byte[] bytesdata = Encoding.ASCII.GetBytes(str);
                    ns.BeginWrite(bytesdata, 0, bytesdata.Length, new AsyncCallback(SendCallBack), ns);
                    ns.Flush();
                    queueRevStr.Enqueue("向中心服务器发送数据:"+str);
                }
                catch (Exception e)
                {
                    //listBoxStatus.Items.Add("SendData(发送数据异常):" + e.Message);
                }
            }
            private void SendCallBack(IAsyncResult iar)
            {
                try
                {
                    if(ns!=null)
                        ns.EndWrite(iar);
                    else
                        listBoxStatus.Invoke(setlistboxcallback, "与中心服务器连接中断,无法发送数据!");
                }
                catch (Exception e)
                {
                    listBoxStatus.Invoke(setlistboxcallback, "SendCallBack(发送回调异常):" + e.Message);
                }
            } //从服务器端收到的数据显示在RichTextBox里
            private void SetRichTextBoxReceive(string str)
            {
                richTextBoxRecv.AppendText(str);
            }       
            
            private void timerSend_Tick(object sender, EventArgs e)
            {
                evReadFromT.OnrtspEvent(this, e);
            }        private void InfoForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (client != null && client.Client.Connected)
                {
                    client.Close();
                    client.Client.Close();
                }
            }    }
        public delegate void delegateReadTSerialPort(object sender,EventArgs e);
        class eventReadFromT
        {
            public event delegateReadTSerialPort rtspEvent;
            public void OnrtspEvent(object sender,EventArgs e)
            {
                if (rtspEvent != null)
                    rtspEvent(sender,e);
            }
        }
      

  4.   

    没耐心看你的代码了, 算是个异步通信的联系作吧。遗留数据。  应该是你在服务端作了一定的错误处理,而第二次关闭客户端后,服务器的遗留数据会影响之后的读取。
    另外你下边这个判断有问题。要判断网络断开这可不行,问题多多
       if (datareadwrite.ns.CanRead) 
                    { 
                        datareadwrite.ns.BeginRead(datareadwrite.read, 0, datareadwrite.read.Length, ReadCallBack, datareadwrite); 
                        queueRevStr.Enqueue("开始接收数据……"); 
                    } 
                    else 
                        queueRevStr.Enqueue("客户端程序已经关闭"); 
                    allDone.WaitOne(); 
      

  5.   

    看到有人在MSDN上发过类似的帖子,好象没有任何人反应。哪位大牛能给个明确的指点呀,急地火烧火燎……