簡體   English   中英

C#中如何從服務器接收數據到客戶端

[英]How to receive data from server to client in C#

我的客戶端程序在文本框中獲取用戶的輸入,將其發送到服務器,服務器通過將消息大寫來處理它並將其發送回客戶端。 我客戶端的代碼通過使用 Socket.Send() 方法將字符串發送到服務器來工作。 為了向服務器發送多個請求,我確保在發送消息后調用 Socket.Disconnect()但是當我嘗試使用 Socket.Receive(byte[],...) 從服務器接收緩沖區時。 服務器打印初始消息,然后拋出錯誤Unable to read data from the transportation stream because the remote device ended the connection forcibly . 我確實知道該錯誤是因為我嘗試接收消息然后調用 Disconnect,我怎樣才能正確地確保我從服務器收到消息但仍然發送盡可能多的消息。 下面是我的代碼

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();  
                }
            };

            
        }

您應該知道您的接收不會像您預期的那樣工作。 TCP 不發送消息,它是一個 stream 字節。 您必須不斷循環接收,直到收到所有數據。 這反過來又要求您知道您期望的信息有多大。

這可能是也可能不是你當前錯誤的原因,但一旦你遇到更復雜的真實案例,它就會在以后失敗

當您使用 sockets 時,您必須定義自己的協議。 您從另一端接收數據作為字節序列,您就是賦予這些字節意義的人。 例如,您可以使用此協議:

  • 前 4 個字節是一個帶有消息大小的數字(包括或不包括這 4 個字節,由您選擇)
  • 接下來的字節是消息的內容

在這種情況下,當您收到字節時,您需要:

  • 將接收到的字節保存在某個緩沖區中。
  • 你有少於 4 個字節嗎? 等待更多字節。
  • 你有4個字節嗎? 然后您知道消息的長度(假設 73 個字節,例如):等待更多字節。
  • 你有超過4個字節嗎? 是的,你有 44 個字節。 44 小於 73...消息不完整:等待更多字節。
  • 現在你有 84 個字節:你可以創建/解碼你的消息(你有 73 個字節)。 您還有一些字節,用於下一條消息。 重復這個過程(你有長度嗎?你有內容嗎?...)

如果您使用(或檢查源代碼)Mina .NET,您已經實現了很多東西(緩沖區...)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM