简体   繁体   English

异步Tcp Server无法接收数据

[英]Async Tcp Server cannot receive data

I am currently tyring to create a Multi threading and async tcp server that implements the Tcpl listener 我目前正在尝试创建实现Tcpl侦听器的多线程和异步tcp服务器

Current the server is working as intended as i am able to send data to the server an transmit data to the client with out any problems 当前服务器正在按预期工作,因为我能够将数据发送到服务器并将数据发送到客户端而没有任何问题

However after i have sent data to the server and then sent data back to the client, when the client sends data back to the server again the server is unabe to pick up the data 但是,在我将数据发送到服务器然后又将数据发送回客户端之后,当客户端再次将数据发送回服务器时,服务器将无法取回数据

I have tried for days to find an answer to this problem however with no luck 我已经尝试了好几天才能找到这个问题的答案,但是没有运气

Here is the code that i am currently using in the server: 这是我当前在服务器中使用的代码:

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);
        }
    }
}

Thanks All 谢谢大家

You should call BeginAcceptTcpClient in AcceptTcpClientCallback also. 您还应该在AcceptTcpClientCallback调用BeginAcceptTcpClient You don't accept any new connection after the first one. 在第一个连接之后,您不接受任何新连接。

BeginReadCallback函数中,释放用于调用BeginRead的对象,然后尝试运行代码而不使用dispose函数,而仅在切换条件下调用GetRespone函数,请尝试在BeginReadCallback函数中调用BeginRead

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM