0

我目前正在努力创建一个实现 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);
        }
    }
}

谢谢大家

4

2 回答 2

1

你也应该打电话BeginAcceptTcpClientAcceptTcpClientCallback。在第一个连接之后,您不接受任何新连接。

于 2012-06-05T09:53:28.293 回答
0

在您的BeginReadCallback函数中,您处置了您用来调用的对象,BeginRead尝试在没有处置函数的情况下运行代码,并且您仅GetRespone在切换条件下调用该函数,请尝试BeginRead在您的BeginReadCallback函数中调用。

于 2012-09-14T08:12:47.467 回答