【问题标题】:Sending Binary 0 over socket connection in c#/.Net在 c#/.Net 中通过套接字连接发送二进制 0
【发布时间】:2015-04-16 23:56:20
【问题描述】:

我正在开发一个应用程序,我需要通过套接字连接发送命令,然后接收它发回的数据。发送命令后,我很难从服务器取回任何东西。最初有人告诉我“以二进制 0 结束包”,我认为这可能会让我失望,因为我不确定如何在 c# 中执行此操作。这是一些源代码:

    Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                sender.Connect(remoteEp);
                Console.WriteLine("Socket connected to {0}", sender.RemoteEndPoint.ToString());
                byte zero = Encoding.Default.GetBytes("0")[0];

                byte[] msg = Encoding.ASCII.GetBytes("PACK_ALARM.ALARM_GETCOUNTI,294,0" + zero);

                int bytesSent = sender.Send(msg);

                int bytesReceived = sender.Receive(bytes);
                Console.WriteLine("Test = {0}", Encoding.ASCII.GetString(bytes, 0, bytesReceived));

                sender.Shutdown(SocketShutdown.Both);
                sender.Close();
            }
            catch (ArgumentNullException ane)
            {
                Console.Write("ArgumentNullException : {0}", ane.ToString());
            }
            catch (SocketException se)
            {
                Console.WriteLine("Socket Exception : {0}", se.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception : {0}", e.ToString());
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

【问题讨论】:

  • 您发送的是 text 0,而不是 binary 0。只需发送文字0。或者,既然您已经在发送文本,只需在其末尾添加 \0

标签: c# .net sockets binary


【解决方案1】:

您没有发送二进制零。您正在发送字符 '0' 的 ASCII 表示,转换为数字,转换为字符串。

相反,只需这样做:

byte[] msg = Encoding.ASCII.GetBytes("PACK_ALARM.ALARM_GETCOUNTI,294,0\0");

\0 是空字符的文字 - 二进制零。

另外,请注意 TCP 是流协议,而不是基于消息的协议。您应该将Receiveing 保持在一个循环中,直到您收到整个消息。简而言之,不常见的消息,您的代码可能会工作(不可靠),但任何真正的通信都会导致可怕的混乱。

【讨论】:

  • 感谢您的快速回复。我更改了我的代码以匹配您对消息字符串的建议,但我仍然无法通过接收方法到 Console.WriteLine 调用。即使我还没有循环,如果这有效,我还会得到一些回报吗?此外,要继续接收直到我收到整个消息,请在此处遵循解决方案:stackoverflow.com/questions/7126985/… 帮助?感谢您的帮助。
  • @Kyle 您可能还做错了其他事情。 bytesSent 是否与 msg.Length 具有相同的值?另外,你为什么使用原始的Sockets 而不是TcpClient?至于继续接收部分,是的,这就是它的要点 - 但请注意,该答案的发布者假设您事先知道要接收的消息的大小。由于您的案例是基于文本的协议,因此听起来不太可能。相反,您需要使用缓冲区,并且(显然)按\0 拆分消息。这有点棘手,尤其是如果您以前从未做过类似的事情。
  • @Kyle 您的代码之外也很可能存在问题-每当您执行任何网络代码时,请准备好Wireshark之​​类的东西-您真的想看到在线上发生的所有事情.例如,您将能够查看您的消息是否以正确的方式到达了正确的 IP,以及是否有响应。
  • 我刚刚再次单步执行了我的代码,并且 bytesSent 的值肯定与 msg.Length 相同。我并没有真正考虑甚至不知道 TcpClient 的存在。我假设您建议切换到使用它?过去几个月我一直在做 c# 开发,但从未尝试过任何套接字编程。您对缓冲区的大小有什么建议吗? @Luann
  • @Kyle TcpClient 更容易使用,尤其是在处理异步 I/O 时。网络编程是hard - 在深入研究之前,您可能应该阅读一些有关该主题的内容;遗憾的是,您会发现大多数教程和示例都存在严重缺陷。缓冲区的大小不是什么大问题,对于单个连接,您几乎可以使用任何东西——409616384 之类的东西都可以正常工作。请注意,您既可以只接收部分消息,也可以在一个Receive 中接收多条消息(或TcpClientNetworkStream 上的Read)。这就是关于 TCP 的棘手部分 :)
猜你喜欢
  • 2012-08-23
  • 2011-12-03
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
相关资源
最近更新 更多