簡體   English   中英

空的緩沖區插槽

[英]an empty buffer socket

我有此代碼服務器部分:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using System.Diagnostics;
namespace server
{
    public partial class server : Form
    {
        public  byte[] data;

        public  byte[] data1;
        public static Socket sock ;
        public static List<Socket> sock_li = new List<Socket>();
        public delegate void operation(string s);
        public delegate void operation2();
        public delegate bool verifier();
        public static int nombre = 0;

        public server()
        {
            InitializeComponent();
          this.Show();
          data1 = new byte[1024];
          data = new byte[1024];
          comboBox1.Items.Add(0);
         sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
              IPAddress adress = IPAddress.Parse("127.0.0.1");
              IPEndPoint iep = new IPEndPoint(adress, 4000);
              EndPoint ep = (EndPoint)iep;
              sock.Bind(iep);
              sock.Listen(1000);
               sock_li.Add(sock.Accept());

               if (this.InvokeRequired) Invoke((operation)effectuer4, "le client " + 0 + " a rejoint le chat");
               else effectuer4("le client " + 0 + " a rejoint le chat");
               Thread li = new Thread(liste);
               li.Start();

               Thread ko = new Thread(new ParameterizedThreadStart(listenning));
               ko.Start(0);
          }
        public void liste() {
            nombre = 1;
        while (true)
              {
                  sock_li.Add(sock.Accept());
                  if (this.InvokeRequired) Invoke((operation)effectuer4, "le client " + nombre.ToString() + " a rejoint le chat");
                  else effectuer4("le client " + nombre.ToString() + " a rejoint le chat");
                  if (this.InvokeRequired) Invoke((operation)effectuer5,  nombre.ToString() );
                  else effectuer5( nombre.ToString() );
                  Thread ko = new Thread(new ParameterizedThreadStart(listenning));
                  ko.Start(nombre);
                  nombre++;
              }




        }

        private void effectuer5(string p)
        {
            comboBox1.Items.Add(p);
        }
        public void listenning(Object j)
        {

            int i = (int)j;

            String s="";
            while (true)
            {
                if (sock_li[i].Receive(data) > 0)
                {
                 s = ASCIIEncoding.ASCII.GetString(data);

                              if (this.InvokeRequired) Invoke((operation)effectuer4, "client " + i.ToString() + " : " + s);
                              else effectuer4("client " + i.ToString() + " : " + s);


                }

            }
        }
        private void effectuer(String s)
        {
            textBox1.Text += "serveur:  " + s + "\r\n";
              message.Text  = "";
        }
        private void effectuer4(String s)
        {
            textBox1.Text +=  s + "\r\n"; message.Text = "";

        }

      private void buttonDisconnect_Click(object sender, EventArgs e)
        {
            sock.Close();
            Application.Exit();
             }
    private void buttonSend_Click(object sender, EventArgs e)
        {
           String s = message.Text ;
           data1.Initialize();
            data1 = System.Text.Encoding.ASCII.GetBytes(s);


            int i = int.Parse(comboBox1.SelectedItem.ToString());
            sock_li[i].Send(data1);

       if (InvokeRequired) Invoke((operation)effectuer, s); else effectuer(s);

           }
        }
     }

部分客戶是:

 using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Timers;
    using System.Threading;
    using TrackingUnitSimulator;
    using NHibernate;
    using System.Xml;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Diagnostics;
    using base_donnee;

    namespace GUInterface
    {
        public partial class TrackingUnitClientForm : Form
        {
            #region variables
            public string fich_log = "";
            public Socket sock;
            public IPEndPoint ipEnd = null;
            public static bool connexion = false;
            private static byte[] data;
            public static byte[] data1;
            public  string serial;
            public string[] types= new string[6]{  "EasyTrace"," WatchTrace","MultiTrace","PocketTrace","TrailerTrace","SmartTrace"};
            public static string[] typ = new string[100];
            public static string[] validite = new string[100];
            public static float[] longi = new float[100];
            public static float[] lati = new float[100];
           public static float[] scenarios = new float[100];
            public static int nombre = 0;
           public static TCPClient tcpClient = null;
           public static int[] tab = new int[6];
           public static int debut = 0;
           public static int fin = 0;
           public static string s;
           public int atte = 0;

            public static scenario sc = null;
            #endregion
           #region delegates
           delegate void CommandReceivedCallBack(TCPClient tcpClient, string commandText);
           delegate void faire(string s);
           delegate void faire2(string s1, string s2);
           delegate void masquer(int i);
           delegate void received(string i);
           #endregion


            public void received1(string i)
            {
                receivedCommand.Text += "  New command: " + i + "\r\n";
            }

            #endregion

            public TrackingUnitClientForm(string b, bool ver, string fichier_log, string fichier_scenario)
            {
                InitializeComponent();
                fich_log = fichier_log;
                Disconnexionbt.Hide();
                sc = new scenario(@fichier_scenario);
                serial = b;
                int p = 0;
                Random m = new Random();
                p = m.Next(0, 5);
                if (ver == true)
                {
                    equipment cr = new equipment();
                    cr.enregistrer(b, types[p]);
                }
                label4.Text = types[p];
                label2.Text = serial;

                if (fich_log != "")
                {

                    if (InvokeRequired) Invoke((faire)log, DateTime.Now.ToString() + " | " + "L'équipment num" + serial.ToString() + " se connecte\r\n");
                    else log(DateTime.Now.ToString() + " | " + "L'équipment num" + serial.ToString() + " se connecte\r\n");
                }
                connecter();


                  Thread th = new Thread(listening);
                th.Start();


            }

            public void connecter() {
                try
                {
                    IPAddress adress = IPAddress.Parse("127.0.0.1");
                    ipEnd = new IPEndPoint(adress, 4000);
                    sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    sock.Connect(ipEnd);
                    this.Connexionbt.Hide();
                    this.Disconnexionbt.Show();
                    lblConnectionStatus.Text = "Online";
                    lblConnectionStatus.ForeColor = Color.Blue;

                }
                catch (Exception exc)
                {

                    if (InvokeRequired) Invoke((masquer)masquer1, 4);
                    else
                        this.Disconnexionbt.Hide();
                    lblConnectionStatus.Text = "Offline";
                    lblConnectionStatus.ForeColor = Color.Red;
                    MessageBox.Show(exc.Message, Text);
                }
                }
            public void listening() {
                String s = null;
               try
                {
                repeter:

                    data = new byte[1024];
                s = ASCIIEncoding.ASCII.GetString(data);
                    if (sock.Receive(data) > 0 && s!="")
                    {


                        if (String.Compare(s, "$$Y01") == 0)
                        {
                            if (InvokeRequired) Invoke((received)received1, "Actual Postion Request"); else received1("Actual Postion Request");
                        }
                        else if (String.Compare(s, "$$Y03") == 0)
                        {
                            if (InvokeRequired) Invoke((received)received1, "Stop The Vehicle"); else received1("Stop The Vehicle");
                        }
                        else if (String.Compare(s, "$$Y06") == 0)
                        {
                            if (InvokeRequired) Invoke((received)received1, "Cancel The Stop"); else received1("Cancel The Stop");
                        }
                        else
                        {
                            if (InvokeRequired) Invoke((received)received1, s); else receivedCommand.Text += s + "\r\n";
                        }

                    }
                    data = new byte[0];
                    goto repeter;

                }
                catch { }
            }



        }
    }

但是我有這個問題:當我執行兩個以上的客戶端時,某些消息將是空的,尤其是第一個(緩沖區數據為空!)。我該如何解決這個問題?

 data = new byte[1024];
 s = ASCIIEncoding.ASCII.GetString(data);
 if (sock.Receive(data) > 0 && s!="")
 {

k ...這將分配一個新的緩沖區(全零),對該全零緩沖區進行解碼以獲取一個字符串( s ), 然后實際上請求數據(不考慮任何類型的“成幀”),而無需對數據進行解碼接收,然后將s (我們知道它來自全零)與許多我們已經知道不是的預期字符串進行比較

因此,是的,第一個“接收”將總是錯過您的切換,僅僅是因為您未正確解碼。 然而! 不得假定每個“接收”都將從單個“發送”中獲取數據。 這里的TCP只是一個流。 您將獲得“一些數據”,該數據可能是:

  • 如果您真的很幸運,則只發送一條消息
  • 消息的一部分
  • 27條小訊息
  • 一條消息的結尾,整個第二條消息以及第三條的開始(不完整)

這就是為什么您需要使用“成幀”來檢測流中的子消息的原因,例如在基於文本的協議中查找換行符,或在二進制協議中使用長度前綴數據。

由於這是ASCII,因此您不必擔心部分字符,但是仍然需要保留Receive的結果,以便知道要查看內部data字節數(即,如果從中僅獲得27個字節)套接字,則只能解碼 27個字節)。

您可能會發現這對於進一步了解此很有用

暫無
暫無

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

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