TechGeek
TechGeek

Reputation: 326

How to receive data from server to client in C#

My client program takes input from a user in a text box, sends it to a server which processes it by capitalizing the message and sends it back to the client. The code in my client side works by as it sends the string to the server using the Socket.Send() method. In order to send multiple requests to the server , I made sure I called Socket.Disconnect() after I sent the message, now this works if I do not try to receive any bytes into the client object and prints as many messages as I want but when I tried to receive the buffer from the server using the Socket.Receive(byte[],...). The server prints the initial message and then throws an error that Unable to read data from the transportation stream because the remote device ended the connection forcibly. I do understand that error was because I try to receive the message and then call Disconnect, How can I properly make sure that I receive the message from the server but still send as many messages as I can. Below is my code

public class MainActivity : AppCompatActivity
    {
        //declare the textview to display the data we will recieve from the server
        TextView _data;
        //declare the port integer where the server is listening
        protected readonly int port = 13000;
        //declare the ip address as a string
        protected readonly string host = "192.168.49.147";
        //grab a reference to the button we wil use for sending the mesage
        protected Button send_message;
        //grab a reference to the message typed in by user
        protected EditText _message;
        //declare the object to hold the client details for us
        protected Socket _client;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);
            send_message=FindViewById<Button>(Resource.Id.send_message);
            _message=FindViewById<EditText>(Resource.Id.message);
            _data = FindViewById<TextView>(Resource.Id.textView1);
            
            //register a listener for the send mesage onclick event
            send_message.Click += (o, e) => {
                //notice we have used a delegate handler
                //check if the field is empty
                if (_message.Text == string.Empty)
                {
                    _message.SetError("An input is required here", null);
                    _message.RequestFocus();
                    return; //means no more code is processed

                }
                //if the user has typed in text, prepare to send to the server
                //grab the text from the control
                string text=_message.Text;
                //convert the string to byte array
                byte[] msg=System.Text.Encoding.UTF8.GetBytes(text);  
                //prepare a new client to connect to the address
                try
                {
                    //create a new instance of the tcp client object
                    _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    _client.Connect(host, port);
                    if (_client.Connected)
                    {
                        //attempt to send a message
                        _client.Send(msg, msg.Length, SocketFlags.None);
                        //attempt to receive the message
                        byte[] rec= new byte[msg.Length];
                        _client.Receive(rec, 0, SocketFlags.None);
                        string received=System.Text.Encoding.ASCII.GetString(rec);
                        //update the date on the texview
                        _data.Text=received;

                        //disconnect and reuse client
                        _client.Disconnect(true);
                        
                    }
                    else
                    {
                        Snackbar.Make(_message, "The socket is not yet connected", Snackbar.LengthLong).Show();
                    }
                   ;
                }
                catch (SocketException ed)
                {
                    Snackbar.Make(_message,ed.Message,Snackbar.LengthLong).Show();  
                }
            };

            
        }

Upvotes: 0

Views: 460

Answers (2)

Victor
Victor

Reputation: 2371

When you work with sockets, you must define your own protocol. You receive data from the other side as a sequence of bytes and you are who give sense to this bytes. For example, you can use this protocol:

  • First 4 bytes are a number with the size of the message (including or not this 4 bytes, it's your choice)
  • Next bytes are the content of message

In this case, when you receive the bytes, you need:

  • Save in some buffer the received bytes.
  • Do you have less than 4 bytes? Wait for more bytes.
  • Do you have 4 bytes? Then you know the length (suppose 73 bytes, as an example) of the message: wait for more bytes.
  • Do you have more than 4 bytes? Yes, you have 44 bytes. 44 are less than 73... the message is not complete: wait for more bytes.
  • Now you have 84 bytes: You can create/decode your message (you have the 73 bytes). You have some more bytes, for next message. Repeat the process (have you the lenght? have you the content?...)

If you use (or check the source code) Mina .NET, you have lots of things (buffers...) already implemented.

Upvotes: 1

pm100
pm100

Reputation: 50210

You should be aware that your receive will not work as you expect. TCP does not send messages, it is a stream of bytes. You have to keep looping on the receive till you have received all the data. This in turn requires that you know how big the message you expect is.

This may or may not be the cause of you current error, but it will fail later on once you get more complicated real word case going

Upvotes: 2

Related Questions