1

I am developing a proxy which accepts connections from multiple clients. The proxy checks for a valid token from the clients and if the token is found it allows the clients to connect to the server.

I am using SocketAsyncEventArgs, BufferManager and other details from this link

The code is as below.

I am using acceptEventArgs to accept new connections from the clients and using connectEventArgs to connect to the actual server. How do I send the received data from the acceptEventArgs (AcceptSocket) to the connectedEventArgs (ConnectedSocket)

//Code after accepting a socket

private void 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
    }
NewUnhandledException
  • 733
  • 2
  • 10
  • 34
  • Can you provide a more concise example that shows your problem? Dumping 300+ lines of code in question and asking "I am having difficulty in figuring out how to send data" doesn't make it very easy for someone to help you. – Peter Ritchie Sep 21 '12 at 16:57
  • I have recently started using the SocketAsyncEventArgs to accomplish the creation of a proxy that listens on a socket and relays the calls from clients to the Server. The Above Code Does the following Listen on a port >> Accept New connection from client >> Connect to the Server. My question is how to send data from client to the server and visa versa using SocketAsycEventArgs. Its the code that goes into the ProcessClientReceive() and ProcessServerReceive() methods in the above code. – NewUnhandledException Sep 21 '12 at 19:36

0 Answers0