2012-05-09 100 views
0

我有此代码 服务器部分:空缓冲区插座

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个客户端的一些消息将是空的,尤其是第一个(缓冲区数据为空!!)我该如何解决这个问题?

+0

您在连接上发送多少条消息?多?或只有一个?特别是,你的“接收”代码看起来好像完全不考虑任何类型的帧 - 并且似乎期望“接收”数据匹配(在边界上)“发送”数据 - 这是完全不正确的(套接字不尊重和保留“发送” - 它只是一个数据流)。这可能是原因吗? –

+0

在连接中,我想发送很多消息。我如何订购? –

+0

请在我的回答结尾处阅读链接,其中描述了“框架” –

回答

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

ķ......这个分配一个新的缓冲区(全0),这一切都是零缓冲解码得到一个字符串(s),然后实际上请求数据(不考虑任何形式的“框架”的),不会打扰解码接收到的数据,然后将s(我们知道它来自全零)与预期的多个字符串进行比较,其中我们已经知道它是没有的

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

  • 只有一个消息,如果你真的很幸运消息的
  • 部分
  • 27小消息
  • 一个消息的结束和整个第二信息和第三

这就是为什么你需要使用“框架”对甲流检测子消息,例如在文本的找换行字符开始(不完全)基于协议的协议,或使用长度前缀d ata在二进制协议。

由于这是ASCII,您不必担心部分字符,但你仍然需要坚持到Receive结果,让你知道有多少字节来看看里面data(也就是说,如果你只从套接字获得27个字节,您应该只有解码 27个字节)。

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

+0

谢谢你! –