简体   繁体   English

NetworkStream.Write 数据似乎没有到达接收套接字

[英]NetworkStream.Write data seems not to arrive at receiving socket

C# System.Net,Sockets C# System.Net,Sockets

I'm having a problem where I cannot figure out what I might be doing wrong.我遇到了一个问题,我无法弄清楚我可能做错了什么。

The story is, I send byte[] application data from TcpClient socket to another TcpClient socket.故事是,我将 byte[] 应用程序数据从 TcpClient 套接字发送到另一个 TcpClient 套接字。 It all works great, until I add a custom pseudo Athentication test before the application data is sent, after which the send and receive which originally worked, fails.一切都很好,直到我在发送应用程序数据之前添加了一个自定义的伪认证测试,之后最初工作的发送和接收失败了。

I say fails, but what actually occurs is that it only appears to get 3 bytes all set to 0 at the read socket.我说失败了,但实际发生的是它似乎只在读取套接字处将 3 个字节全部设置为 0。

The Authenticate method does the following. Authenticate 方法执行以下操作。 The server end sends 1 byte of data (0-85), the client receives it, treats it as an int, multiplies it by 3 and sends a byte back to server.服务器端发送1个字节的数据(0-85),客户端接收,将其视为一个int,乘以3,然后将一个字节发送回服务器。 Server checks the value, and sends another byte back set to 1.服务器检查该值,并将另一个字节发送回设置为 1。

All of that seems to work fine, but together the data sent by cliend after authentication does not appear to be received, just 3 bytes set to 0.所有这些似乎都可以正常工作,但是客户端在身份验证后发送的数据一起似乎没有被接收到,只有 3 个字节设置为 0。

I want the socket to remain open over the lifetime of the program, so I cannot dispose the stream, as that will also dispose the socket.我希望套接字在程序的生命周期内保持打开状态,因此我无法处理流,因为这也会处理套接字。

Here is the full code for both client and server, in the hope someone might see my mistake, or an issue I have missed.这是客户端和服务器的完整代码,希望有人能看到我的错误,或者我遗漏的问题。

The code is intentionally without error checking for brevity, and is very basic to just show the problem.为简洁起见,该代码有意不进行错误检查,并且只是显示问题的基础。

Note, that if both Authenticate methods simply return true, then the code works exactly how I'd expect it.请注意,如果两个 Authenticate 方法都简单地返回 true,那么代码的工作方式正是我所期望的。

Server.服务器。

class Program
    {
        static Random rnd = new Random(Guid.NewGuid().GetHashCode());
        static void Main(string[] args)
        {
            Process p = Process.Start(@"C:\Users\Teddy\Documents\visual studio 2015\code\Readissue\TheClient\bin\Debug\TheClient.exe");

            Console.Title = "Server";

            TcpListener lis = new TcpListener(
                new IPEndPoint(
                    IPAddress.Any, 4000
                    ));

            lis.Start();

            TcpClient cli = lis.AcceptTcpClient();
            NetworkStream ns = cli.GetStream();

            if (Authenticate(cli, ns))
            {
                Console.WriteLine("Good!");
                // This condition is met
            }
            else
            {
                Console.WriteLine("Bad!");
                Console.ReadLine();
                return;
            }

            // Wait until Carrier class of client
            // Sends data
            while (!ns.DataAvailable)
            {
                Thread.Sleep(100);
            }
            Console.WriteLine("DataAvailable");

            byte[] buffer = new byte[2048];
            //bytesread is always the value of 3.
            int bytesread = ns.Read(buffer, 0, buffer.Length);
            string sdata = Encoding.ASCII.GetString(buffer).Substring(0, bytesread);
            Console.WriteLine(sdata);
            Console.ReadLine();

            p.Kill();
            p.Close();

        }

        private static bool Authenticate(TcpClient cli, NetworkStream ns)
        {
            //return true;
            byte[] rcv = new byte[1];
            int isnd = rnd.Next(0, 85);
            byte[] snd = new byte[1] { (byte)isnd };

            //Sends a random number
            //and waits for response
            ns.Write(snd, 0, snd.Length);
            while (!ns.DataAvailable)
            {
                Thread.Sleep(10);
            }

            // Expects response to be 
            // random number x 3
            int br = ns.Read(rcv, 0, rcv.Length);
            int ircv = rcv[0];

            int iok;
            if (ircv == (isnd * 3))
            {
                // Confirm random number x 3
                iok = 1;
                byte[] bok = new byte[1] { (byte)iok };
                ns.Write(bok, 0, snd.Length);
                return true;
            }
            else
            {
                iok = 0;
                byte[] bok = new byte[1] { (byte)iok };
                ns.Write(bok, 0, snd.Length);
                return false;
            }
        }

        class Carrier
        {
            public double PointX { get; set; }
            public double PointY { get; set; }
            public string Comment { get; set; }

            public Carrier(byte[] bytes)
            {
                string[] tmpStrings = Encoding.ASCII.GetString(bytes)
                    .Split('|');

                PointX = Convert.ToDouble(tmpStrings[0]);
                PointY = Convert.ToDouble(tmpStrings[1]);
                Comment = tmpStrings[2];
            }
        }
    }

Client客户

class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Client";

            IPEndPoint EP = new IPEndPoint(
                    IPAddress.Parse("192.168.1.100"), 4000
                    );

            TcpClient cli = new TcpClient();
            cli.Connect(EP);
            if (!cli.Connected)
            {
                Console.WriteLine("Not connected!");
                return;
            }
            Console.WriteLine("Connected!");
            NetworkStream ns = cli.GetStream();

            if (Authenticate(cli, ns))
            {
                Console.WriteLine("Good!");
                // This condition is met
            }
            else
            {
                Console.WriteLine("Bad!");
                return;
            }

            // Send data to server
            Carrier carrier = new Carrier();
            string stringtosend = carrier.ToString();
            byte[] bytestosend = Encoding.ASCII.GetBytes(stringtosend);
            ns.Write(bytestosend, 0, bytestosend.Length);

            Console.WriteLine("Data sent!");
            Console.ReadLine();

        }

        private static void UseClient(TcpClient cli, NetworkStream ns)
        {
            Console.WriteLine(ns.CanRead);
        }

        private static bool Authenticate(TcpClient client, NetworkStream ns)
        {
            //return true;
            byte[] rcv = new byte[1];
            while (!ns.DataAvailable)
            {
                Thread.Sleep(10);
            }

            int br = ns.Read(rcv, 0, rcv.Length);
            int ircv = rcv[0];
            int result = ircv * 3;
            byte[] snd = BitConverter.GetBytes(result);
            ns.Write(snd, 0, snd.Length);

            while (!ns.DataAvailable)
            {
                Thread.Sleep(10);
            }

            br = ns.Read(rcv, 0, rcv.Length);

            int iok = rcv[0];
            if (iok == 1)
            {
                return true;
            }
            return false;
        }
    }

    class Carrier
    {
        public double PointX { get; set; }
        public double PointY { get; set; }
        public string Comment { get; set; }


        public Carrier()
        {
            PointX = 1.00;
            PointY = 2.00;
            Comment = "A longer comment string";
        }

        public override string ToString()
        {
            return PointX.ToString() + "|"
                + PointY.ToString() + "|"
                + Comment;
        }
    }

So as I suspected, the problem was in the Authenticate method on the client side.所以正如我所怀疑的,问题出在客户端的 Authenticate 方法中。 I was sending an int instead of a single byte.我发送的是 int 而不是单个字节。 The offending line of code was.有问题的代码行是。

byte[] snd = BitConverter.GetBytes(result);

Which should have been.这应该是。

byte[] snd = new byte[1] { (byte)result };

Thanks jdweng for finding the error.感谢 jdweng 发现错误。

PS, thanks to the down-voters for your interest, please accept my sincere pity. PS,感谢投票者对您的关注,请接受我的诚挚遗憾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM