1

我正在开发一个接受来自多个客户端的连接的代理。代理检查来自客户端的有效令牌,如果找到令牌,它允许客户端连接到服务器。

我正在使用此链接中的 SocketAsyncEventArgs、BufferManager 和其他详细信息

代码如下。

我正在使用 acceptEventArgs 接受来自客户端的新连接,并使用 connectEventArgs 连接到实际服务器。如何将接收到的数据从 acceptEventArgs (AcceptSocket) 发送到 connectedEventArgs (ConnectedSocket)

//接受套接字后的代码

私有无效 ProcessAccept(SocketAsyncEventArgs acceptEventArgs){

        if (acceptEventArgs.SocketError != SocketError.Success)
        {
            // Loop back to post another accept op. Notice that we are NOT
            // passing the SAEA object here.
            LoopToStartAccept();

            //AcceptOpUserToken theAcceptOpToken = (AcceptOpUserToken)acceptEventArgs.UserToken;
            //Console.WriteLine("SocketError, accept id " + theAcceptOpToken.TokenId);

            //destroy the socket, since it could be bad.
            HandleBadAccept(acceptEventArgs);

            return;
        }

        Int32 max = Program.maxSimultaneousClientsThatWereConnected;
        Int32 numberOfConnectedSockets = Interlocked.Increment(ref this.numberOfAcceptedSockets);
        if (numberOfConnectedSockets > max)
        {
            Interlocked.Increment(ref Program.maxSimultaneousClientsThatWereConnected);
        }

        Console.WriteLine("Simultaneous connections {0} ", max.ToString());
        LoopToStartAccept();

        // Get a SocketAsyncEventArgs object from the pool of receive/send op 
        //SocketAsyncEventArgs objects
        SocketAsyncEventArgs receiveSendEventArgs = this.poolOfRecSendEventArgs.Pop();

        //A new socket was created by the AcceptAsync method.
        //object which will do receive/send.
        receiveSendEventArgs.AcceptSocket = acceptEventArgs.AcceptSocket;

        //We have handed off the connection info from the
        //accepting socket to the receiving socket. So, now we can
        //put the SocketAsyncEventArgs object that did the accept operation 
        //back in the pool for them. 
        acceptEventArgs.AcceptSocket = null;
        this.poolOfAcceptEventArgs.Push(acceptEventArgs);

        //Accepting has completed now connect to the TestServer Server
        StartConnecting(receiveSendEventArgs);

    }

    private void LoopToStartAccept()
    {
        StartAccepting();
    }

    /// <summary>
    /// Connects to the TestServer Server
    /// </summary>
    /// <param name="acceptArgs"></param>       
    internal void StartConnecting(SocketAsyncEventArgs receiveSendEventArgs)
    {
        SocketAsyncEventArgs connectEventArgs;

        //Get a SocketAsyncEventArgs object to connect to  the TestServer Server.  

        //Get it from the pool if there is more than one in the pool.
        //using 1 as the lower limit for safety sake           
        if (this.poolOfConnectEventArgs.Count > 1)
        {
            try
            {
                connectEventArgs = this.poolOfConnectEventArgs.Pop();
            }
            //or make a new one.
            catch
            {
                connectEventArgs = CreateNewSaeaForConnect(poolOfConnectEventArgs);
            }
        }
        //or make a new one.
        else
        {
            connectEventArgs = CreateNewSaeaForConnect(poolOfConnectEventArgs);
        }




        //connect to the server
        IPAddress ipAddress_TestServer_ADS = new IPAddress(new byte[] { 192, 201, 240, 89 });
        int port = 8085;

        // Establish the local endpoint for the socket.
        IPEndPoint HostEndPoint = new IPEndPoint(ipAddress_TestServer_ADS, port);

        Socket serverSocket;

        // Create a TCP/IP socket.
        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
        serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1);

        connectEventArgs.RemoteEndPoint = HostEndPoint;

        //Store the receive Send event args in the UserToken
        connectEventArgs.UserToken = receiveSendEventArgs;



        //bool completedSynchronously = receiveSendEventArgs.AcceptSocket.ConnectAsync(connectEventArgs);
        bool completedSynchronously = serverSocket.ConnectAsync(connectEventArgs); 


        if (!completedSynchronously)
        {
            ProcessConnection(connectEventArgs);
        }
    }



    private void ConnectEventArg_Completed(object sender, SocketAsyncEventArgs e)
    {
        Console.WriteLine("ConnectEventArg_Completed, id ");

        ProcessConnection(e);

    }



    private void ProcessConnection(SocketAsyncEventArgs connectEventArgs)
    {

        //get the receiveSendEventArgs 
        SocketAsyncEventArgs receiveSendEventArgs = (SocketAsyncEventArgs)connectEventArgs.UserToken;

        // This is when there was an error with the connect operation.Close the socket
        if (connectEventArgs.SocketError != SocketError.Success)
        {
            //destroy the server socket, since it could be bad.
            HandleBadConnect(connectEventArgs);

            //destroy the client socket since its of no use either 

            return;
        }

        Console.WriteLine("Connected to TestServer Server ");


        //Read data from the client socket and the Server Socket
        StartReceive(receiveSendEventArgs, connectEventArgs);


    }






    // Set the receive buffer and post a receive op.
    private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs,SocketAsyncEventArgs TestServerreceiveSendEventArgs)
    {
        //Create a state object to store the state
        StateObject state = new StateObject();

        //Set the buffer for the receive operation.
        receiveSendEventArgs.SetBuffer(state.clientReadBuffer, 0, StateObject.BUFFER_SIZE);

        //Set the buffer for the receive from TestServer operation.
        TestServerreceiveSendEventArgs.SetBuffer(state.serverReadBuffer, 0, StateObject.BUFFER_SIZE);

        state.clientSocketAsyncEventArgs = receiveSendEventArgs;
        state.serverSocketAsyncEventArgs = TestServerreceiveSendEventArgs;

        receiveSendEventArgs.UserToken = state;
        TestServerreceiveSendEventArgs.UserToken = state;

        // Post async receive operation on the socket.
        bool completedClientRecieveSynchronously = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
        bool completedServerReceiveSynchronously = TestServerreceiveSendEventArgs.ConnectSocket.ReceiveAsync(TestServerreceiveSendEventArgs);


        if (!completedClientRecieveSynchronously)
        {
            ProcessClientReceive(receiveSendEventArgs);

        }

        if (!completedServerReceiveSynchronously)
        {
            ProcessServerReceive(TestServerreceiveSendEventArgs);
        }
    }



    private void ProcessClientReceive(SocketAsyncEventArgs receiveSendEventArgs)
    {
        //check for Token and write to the Server socket


        // If there was a socket error, close the connection. 
        if (receiveSendEventArgs.SocketError != SocketError.Success)
        {
            CloseClientSocket(receiveSendEventArgs);
            return;
        }

        // If no data was received, close the connection. This is a NORMAL
        // situation that shows when the client has finished sending data.
        if (receiveSendEventArgs.BytesTransferred == 0)
        {
            CloseClientSocket(receiveSendEventArgs);
            return;
        }

        if (receiveSendEventArgs.BytesTransferred > 0) //write to the server side socket
        {

                //How do I write to the server socket ..do not have an handler to the server socket.
        }



    }

    private void ProcessServerReceive(SocketAsyncEventArgs TestServerreceiveSendEventArgs)
    {
        //Write to the client socket
    }
4

0 回答 0