代码之家  ›  专栏  ›  技术社区  ›  UnkwnTech

仅插座接收部分信息C#

  •  1
  • UnkwnTech  · 技术社区  · 16 年前

    我有一段代码正在接收一系列消息:

    byte[] buffer = new byte[10240];
    //...
    sock.Receive(buffer);
    string response = message(buffer);
    Console.WriteLine("Message Recieved");
    if (!verifyUser(response, sock))
    Console.WriteLine("User Invalid");
    //...
    static private bool verifyUser(string userString, Socket sock)
    {
       string[] userData = userString.Split(' ');
       int i = 0;
       while (true)
        {
            if (userData[0].ToUpper() != "USER")
            {
               byte[] buffer = message("WHO");
               sock.Send(buffer);
               userData = userString.Split(' ');
               i++;
               if (i > 4)
               {
                            return false;
                        }
                        continue;
                    }
                    else
                        break;
                }
    Console.WriteLine("Connection recieved from " + userData[1] + " with hash of "/* + userData[2]*/);
    }
    

    我遇到的问题是,如果我提交用户名unknwtech,所有显示它的内容都是unknt,第二个值似乎永远不会出现。 发送数据的应用程序如下所示:

    static void Main(string[] args)
            {
                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                EndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 200);
                sock.Connect(remoteEP);
                byte[] buffer = Encoding.ASCII.GetBytes("USER unkwntech a3f5h4a35sfg");//Made up hash
                sock.Send(buffer);
                sock.Receive(buffer);
                Console.WriteLine(Encoding.ASCII.GetString(buffer));
                Console.ReadLine();
            }
    
    2 回复  |  直到 11 年前
        1
  •  7
  •   Jon Skeet    16 年前

    你是 假设 当你发送的时候,所有的数据都集中在一个包里,你将在另一端接收所有的数据。这不是TCP/IP的工作方式。这是一个流协议——你不应该对一次能收到多少数据做任何假设。

    基本上,您需要从流中读取,直到您已经读取了所有数据,并且套接字已经关闭,或者直到您获得了“足够”的数据。如果你控制着协议,并且它是一个会话协议,那么如果你发送的每一条消息都以它的长度作为前缀,这会使生活变得更加容易——这意味着另一端知道会有多少数据。

        2
  •  1
  •   LandedGently    16 年前

    检查套接字的返回值。接收调用。它返回接收的字节数。您可以将此调用放入循环中并读取,直到获得预期的字节数为止。您还应该通过设置最大尝试次数来防止无限循环,或者按照约翰的建议,检查套接字的状态。另外,不要假设返回值为零意味着你已经阅读了整个消息。

    如果您的协议中每个消息的前缀都是其长度,为了真正防弹,您的协议还应该定义一个标记字节来标记前缀长度头的结尾。一次读取一个字节,直到看到标记字节。然后计算消息的长度,并以更大的块读取,直到您全部读取为止。

    receive定义了一个重载,该重载允许您指定要接收的字节数。(但是,您不能保证收到那么多,因此您仍然需要检查返回值。)