Async Tcp Server无法接收数据

时间:2012-06-05 09:40:34

标签: c# multithreading asynchronous tcp

我目前正在创建一个实现Tcpl监听器的多线程和异步tcp服务器

当前服务器正在按预期工作,因为我能够将数据发送到服务器,向客户端传输数据而不会出现任何问题

然而,在我将数据发送到服务器然后将数据发送回客户端之后,当客户端再次将数据发送回服务器时,服务器无法获取数据

我已经尝试了几天找到这个问题的答案,但没有运气

以下是我目前在服务器中使用的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
using System.IO;

namespace MyTcpAsyncClass
{
    public class StateObject
    {
        public TcpClient MyTcpClient = null;
        public NetworkStream MyNetworkStream = null;
        public const int MyBufferSize = 1024;
        public byte[] MyBuffer = new byte[MyBufferSize];
        public string RequestString = "";
        public StringBuilder MyStringBuilder = new StringBuilder();
        char[] RequestChars; // Char array of Request
        const char STX = (char)0x02; // Start Character
        const char FTX = (char)0x03; // Finish Character

        public void Dispose()
        {
            try
            {
                MyTcpClient.Close();
                MyNetworkStream.Close();
                MyNetworkStream.Dispose();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Message:\n" + ex.Message + "\n\nStacktrace:\n" + ex.StackTrace);
            }
        }
    }

    public static class AsyncServerFunctions
    {
        private static int mPort = 0;

        private static ManualResetEvent MyManualResetEvent = new ManualResetEvent(false);

        public static void StartListening()
        {


            //Catch to Tcp Client Connection
            try
            {
                //Get the database connection
                //MyReaderWriterLockSlim.EnterReadLock();
                LoadSettings();
                //MyReaderWriterLockSlim.ExitReadLock();

                TcpListener MyTcpListener = new TcpListener(IPAddress.Any, mPort);
                MyTcpListener.Start();

                while (true)
                {
                    //Set the event to nonsignaled state
                    MyManualResetEvent.Reset();

                    //Start an asynchronous TcpListener to listen for a connection
                    MyTcpListener.BeginAcceptTcpClient(AcceptTcpClientCallback, MyTcpListener);

                    //Wait until a connection is made before continuing
                    MyManualResetEvent.WaitOne();
                }

                MyTcpListener.Stop();
            }
            catch (Exception ex)
            {
                AddErrorLog(ex.Message, ex.StackTrace);
            }
        }

        private static void AcceptTcpClientCallback(IAsyncResult result)
        {
            try
            {
                //BeginAcceptTcpClientCallback
                //Signal the main thread to continue
                MyManualResetEvent.Set();
                //Get the TcpClientNetworkStream:
                TcpListener MyTcpListener = (TcpListener)result.AsyncState;

                //Finish Async Get Client Process
                TcpClient MyTcpClient = MyTcpListener.EndAcceptTcpClient(result);
                StateObject MyStateObject = new StateObject();
                MyStateObject.MyTcpClient = MyTcpClient;
                MyStateObject.MyNetworkStream = MyTcpClient.GetStream();

                //Begin Async read from the NetworkStream
                MyStateObject.MyNetworkStream.BeginRead(MyStateObject.MyBuffer, 0, StateObject.MyBufferSize, new AsyncCallback(BeginReadCallback), MyStateObject);
            }
            catch (Exception ex)
            {
                AddErrorLog(ex.Message, ex.StackTrace);
            }
        }

        private static void BeginReadCallback(IAsyncResult result)
        {
            StateObject MyStateObject = (StateObject)result.AsyncState;
            NetworkStream MyNetworkStream = MyStateObject.MyNetworkStream;
            string MyRequestString = "";


            try
            {
                //Get Request Data here

                if (MyStateObject.MyBuffer.Length > 0)
                {
                    //Store the data recived
                    MyStateObject.MyStringBuilder.Clear();
                    MyStateObject.MyStringBuilder.Append(Encoding.ASCII.GetString(MyStateObject.MyBuffer));

                    //Get the stored Request string
                    MyRequestString = MyStateObject.MyStringBuilder.ToString();

                    //Record the string recived
                    DatabaseFunctions.AddMessageLog("String Recived (BeginReadCallback): " + MyRequestString);

                    //Remove the first and last character
                    MyRequestString = CleanString(MyRequestString);

                    //Record the Request String
                    DatabaseFunctions.AddMessageLog("Request String Recived:" + MyRequestString);

                    //Get the Message Identifier
                    string MessageIdentifier = "";
                    MessageIdentifier = MyRequestString.Substring(0, 2);

                    switch (MessageIdentifier)
                    {
                        case "value":
                            SendResponse(MyStateObject, StartUp(MessageIdentifier, MyRequestString));
                            SendResponse(MyStateObject, SendTransactionStart(MessageIdentifier, MyAmount));
                            GetResponse(MyStateObject);
                            break;
                        default:
                            //***Default Case***
                            SendResponse(MyStateObject, DefaultCase(MyRequestString));
                            break;
                    }

                    //Dispose of the connection
                    MyStateObject.Dispose();
                }
            }
            catch (Exception ex)
            {
                AddErrorLog(ex.Message, ex.StackTrace);
                try
                {
                    MyStateObject.Dispose();
                }
                catch
                {
                    AddErrorLog(ex.Message, ex.StackTrace);
                }
            }
        }

        private static void SendResponse(StateObject pMyStateObject, string pResponseString)
        {
            try
            {
                //Send a response to the client
                //Get bytes from string sent
                byte[] MyResponseBytes = Encoding.ASCII.GetBytes(pResponseString);
                //Get the network stream
                NetworkStream MyNetworkStream = pMyStateObject.MyNetworkStream;
                //Call SendResponseCallback
                MyNetworkStream.BeginWrite(MyResponseBytes, 0, MyResponseBytes.Length, new AsyncCallback(SendResponseCallback), pMyStateObject);
            }
            catch (Exception ex)
            {
                AddErrorLog(ex.Message, ex.StackTrace);
            }
        }

        private static void GetResponse(StateObject pStateObject)
        {
            //This will run a new AsyncCallback To get the response from the client
            NetworkStream MyNetworkStream = pStateObject.MyNetworkStream;
            pStateObject.MyBuffer = new byte[1024];
            MyNetworkStream.BeginRead(pStateObject.MyBuffer, 0, pStateObject.MyBuffer.Length, new AsyncCallback(BeginReadCallback), pStateObject);
        } 

        private static void SendResponseCallback(IAsyncResult result)
        {
            try
            {
                //End the send procedure
                StateObject MyStateObject = (StateObject)result.AsyncState;
                NetworkStream MyNetworkStream = MyStateObject.MyNetworkStream;
                MyNetworkStream.Flush();
            }
            catch (Exception ex)
            {
                AddErrorLog(ex.Message, ex.StackTrace)
            }
        }

        private static void ShowExceptionMessage(string pMessage, string pStacktrace)
        {
            MessageBox.Show("Message:\n" + pMessage + "\n\nStacktrace:\n" + pStacktrace);
        }

        private static void AddErrorLog(string pMessage, string pStackTrace)
        {
            DatabaseFunctions.AddMessageLog("Message:" + pMessage + "; Stacktrace:" + pStackTrace);
        }
    }
}

全部谢谢

2 个答案:

答案 0 :(得分:1)

您也应该在BeginAcceptTcpClient中致电AcceptTcpClientCallback。在第一个之后,您不接受任何新连接。

答案 1 :(得分:0)

在你的BeginReadCallback函数中,你释放了用来调用BeginRead的对象,尝试运行没有dispose函数的代码,你只是在切换条件下调用GetRespone函数,试试在BeginRead函数中调用BeginReadCallback