一个空的缓冲区插槽

时间:2012-05-09 10:22:29

标签: c# nhibernate sockets

我有这个代码 服务器部分:

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 { }
            }



        }
    }

但我有这个问题:当我执行超过2个客户端时,某些消息将为空,尤其是第一个(缓冲区数据为空!!)如何解决此问题?

1 个答案:

答案 0 :(得分:1)

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

k ...这会分配一个新的缓冲区(全零),解码这个全零缓冲区以获得一个字符串(s),然后实际上要求数据(忽略任何一种“框架”),不打扰解码收到的数据,然后将s(我们知道来自全零)与一些我们已经知道它的预期字符串进行比较无

所以是的,第一个“接收”总是会错过你的开关,只是因为你没有正确解码。然而!你绝不能假设每个“接收”将从单个“发送”获取数据。这里的TCP只是一个流。您将获得“一些数据”,可能是:

  • 如果你真的很幸运的话,只有一条信息
  • 消息的一部分
  • 27条小消息
  • 一条消息的结尾,以及整个第二条消息,以及第三条
  • 的开始(不完整)

这就是为什么你需要使用“framing”来检测流上的子消息,例如在基于文本的协议中查找换行符,或者在二进制协议中使用长度前缀数据。

由于这是ASCII,因此您不必担心部分字符,但仍需要保留Receive的结果,以便了解要在{{1}内查看的字节数(即如果你只从套接字获得27个字节,你应该只解码 27个字节)。

You might find this useful进一步了解这一点。