簡體   English   中英

異步Tcp Server無法接收數據

[英]Async Tcp Server cannot receive data

我目前正在嘗試創建實現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);
        }
    }
}

謝謝大家

您還應該在AcceptTcpClientCallback調用BeginAcceptTcpClient 在第一個連接之后,您不接受任何新連接。

BeginReadCallback函數中,釋放用於調用BeginRead的對象,然后嘗試運行代碼而不使用dispose函數,而僅在切換條件下調用GetRespone函數,請嘗試在BeginReadCallback函數中調用BeginRead

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM