Click here to Skip to main content
15,895,782 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have this C# client server application, and I started with the Microsoft documentation Asynchronous Client Socket Example | Microsoft Docs[^] . However, I did need to modify some stuff and I would need for client to send multiple messages to server, and also to get multiple back.
Starting from scratch, for example I am in controller (which is in client) and I Send this message to server:
namespace client.ObjectHandler
{
    public class BaseHandler
    {
        private AsynchronousClient asynchronousClient;

        public static String username;

        public BaseHandler(AsynchronousClient asynchronousClient = null)
        {
            this.asynchronousClient = asynchronousClient ?? new AsynchronousClient();
        }

        public User findByUsername(String username)
        {
            StringBuilder Content = new StringBuilder();
            Content.Append("find user ");
            Content.Append(username);
            Content.Append(" <EOF>");

            Message message = new Message { Content = Content.ToString() };
            asynchronousClient.Send(message);
            asynchronousClient.sendDone.WaitOne();

            asynchronousClient.Receive();
            asynchronousClient.receiveDone.WaitOne();
            var result = asynchronousClient.response;
            return result.userContent;
        }
   
    }
}

hence the server has to do the operations(in my case accessing the database etc). This is client code:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using core;
using System.IO;

namespace client
{
    public class AsynchronousClient
    {
        // The port number for the remote device.  
        private const int port = 9000;

        // ManualResetEvent instances signal completion.  
        public  ManualResetEvent connectDone =
            new ManualResetEvent(false);
        public  ManualResetEvent sendDone =
            new ManualResetEvent(false);
        public  ManualResetEvent receiveDone =
            new ManualResetEvent(false);

        // The response from the remote device.  
        public Message response = new Message();

        private Socket client;

        private IPHostEntry ipHostInfo;
        private IPAddress ipAddress;
        private IPEndPoint remoteEP;

        public AsynchronousClient()
        {
            // Establish the remote endpoint for the socket.  
            // The name of the
            // remote device is "localhost".  
            ipHostInfo = Dns.GetHostEntry("localhost");
            ipAddress = ipHostInfo.AddressList[0];
            remoteEP = new IPEndPoint(ipAddress, port);

            // Create a TCP/IP socket.  
            client = new Socket(ipAddress.AddressFamily,
                    SocketType.Stream, ProtocolType.Tcp);

            // Connect to the remote endpoint.  
            client.BeginConnect(remoteEP,
                new AsyncCallback(ConnectCallback), client);
            connectDone.WaitOne();

        }

        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.  
                Socket client = (Socket)ar.AsyncState;

                // Complete the connection.  
                client.EndConnect(ar);

                Console.WriteLine("Socket connected to {0}",
                    client.RemoteEndPoint.ToString());

                // Signal that the connection has been made.  
                connectDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        public void Receive()
        {
            try
            {
                // Create the state object.  
                StateObject state = new StateObject();
                state.workSocket = client;

                // Begin receiving the data from the remote device.  
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
                
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            
        }

        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the state object and the client socket
                // from the asynchronous state object.  
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                // Read data from the remote device.  
                int bytesRead = client.EndReceive(ar);
               
                Message receivedMessage = new Message();

                if (bytesRead > 0)
                {
                    // There might be more data, so store the data received so far.  
                    
                    receivedMessage = (Message)Serializer.FromStream(new MemoryStream(state.buffer));
                    // Get the rest of the data.  
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    // All the data has arrived; put it in response.  
                    
                    response = receivedMessage;
                    
                    // Signal that all bytes have been received.  
                    receiveDone.Set();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        public void Send(Message message)
        {
            // Convert the string data to byte data using ASCII encoding.
            MemoryStream stream = Serializer.ToStream(message);
            byte[] byteData = stream.GetBuffer();

            // Begin sending the data to the remote device.  
            client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), client);
        }

        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.  
                Socket client = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.  
                int bytesSent = client.EndSend(ar);
                Console.WriteLine("Sent {0} bytes to server.", bytesSent);

                // Signal that all bytes have been sent.  
                sendDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }
}

and server code:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using core;
using server;


public class AsynchronousSocketListener
{
    // Thread signal.  
    public static ManualResetEvent allDone = new ManualResetEvent(false);

    private IPHostEntry ipHostInfo;
    private IPAddress ipAddress;
    private IPEndPoint localEndPoint;

    private Socket listener;

    public AsynchronousSocketListener()
    {
        // Establish the local endpoint for the socket.  
        // The DNS name of the computer  
        // running the listener is "localhost".  
        ipHostInfo = Dns.GetHostEntry("localhost");
        ipAddress = ipHostInfo.AddressList[0];
        localEndPoint = new IPEndPoint(ipAddress, 9000);

        // Create a TCP/IP socket.  
        listener = new Socket(ipAddress.AddressFamily,
             SocketType.Stream, ProtocolType.Tcp);
    }

    public void StartListening()
    {
        // Bind the socket to the local endpoint and listen for incoming connections.  
        try
        {
            listener.Bind(localEndPoint);
            listener.Listen(100);

            while (true)
            {
                // Set the event to nonsignaled state.  
                allDone.Reset();

                // Start an asynchronous socket to listen for connections.  
                Console.WriteLine("Waiting for a connection...");
                listener.BeginAccept(
                    new AsyncCallback(AcceptCallback),
                    listener);

                // Wait until a connection is made before continuing.  
                allDone.WaitOne();
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();

    }

    public static void AcceptCallback(IAsyncResult ar)
    {
        // Signal the main thread to continue.  
        allDone.Set();

        // Get the socket that handles the client request.  
        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        // Create the state object.  
        StateObject state = new StateObject();
        state.workSocket = handler;
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);
    }

    public static void ReadCallback(IAsyncResult ar)
    {
        String content = String.Empty;

        // Retrieve the state object and the handler socket  
        // from the asynchronous state object.  
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        // Read data from the client socket.
        int bytesRead = handler.EndReceive(ar);
        
        Message receivedMessage = new Message();
        if (bytesRead > 0)
        {
            // There  might be more data, so store the data received so far.  
            
            receivedMessage = (Message)Serializer.FromStream(new MemoryStream(state.buffer));
            // Check for end-of-file tag. If it is not there, read
            // more data.  
            content = receivedMessage.Content;
            if (content.IndexOf("<EOF>") > -1)
            {
                // All the data has been read from the
                // client. Display it on the console.  
                Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                    content.Length, content);
                HandleMessage.handle(handler, receivedMessage);
                // Echo the data back to the client.
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
               new AsyncCallback(ReadCallback), state);
                //Send(handler, receivedMessage);

            }
            else
            {
                // Not all data received. Get more.  
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
            }
        }
    }

    private static void Send(Socket handler, Message message)
    {
        // Convert the string data to byte data using ASCII encoding.
        MemoryStream stream = Serializer.ToStream(message);
        byte[] byteData = stream.GetBuffer();
        // Begin sending the data to the remote device.  
        handler.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), handler);
    }

    private static void SendCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.  
            Socket handler = (Socket)ar.AsyncState;

            // Complete sending the data to the remote device.  
            int bytesSent = handler.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to client.", bytesSent);

            //handler.Shutdown(SocketShutdown.Both);
            //handler.Close();

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

  
}

and the method handle from handleMessage does this:
using System;
namespace server
{
    public static class HandleMessage
    {
        private static BaseHandler baseHandler;

        public static void handle(Socket handler, Message message)
        {
            baseHandler = new BaseHandler();
            String[] received = message.Content.Split(' ');
            if(received[0].CompareTo("find") == 0)
            {
                if(received[1].CompareTo("user") == 0)
                {
                    var result = baseHandler.filterByUsername(received[2]);

                    Message sentMessage = new Message { userContent = result };
                    MemoryStream stream = Serializer.ToStream(sentMessage);
                    var bytesSent = handler.Send(stream.GetBuffer());
                    
                }
            }
        } 
    }
}


What I have tried:

I tried to put in the server after send(handler, message) beginReceive but my code is blocking and I don't find anything helpful
Posted
Updated 15-May-20 11:27am

It's an question-and-response protocol; you're probably getting out of sync with your unacknowledged sending. The transport layer handles the "buffering".
 
Share this answer
 
v2
Quote:
Why my server is receiving a less number of bytes than the client is sending?

You have many parts of code on client and server. My first move is to narrow the search.
I would use a packet analyzer to capture traffic between client and server.
By analyzing the capture, you will see where the chars get lost.
Packet analyzer - Wikipedia[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900