簡體   English   中英

NetworkStream.Write 數據似乎沒有到達接收套接字

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

C# System.Net,Sockets

我遇到了一個問題,我無法弄清楚我可能做錯了什么。

故事是,我將 byte[] 應用程序數據從 TcpClient 套接字發送到另一個 TcpClient 套接字。 一切都很好,直到我在發送應用程序數據之前添加了一個自定義的偽認證測試,之后最初工作的發送和接收失敗了。

我說失敗了,但實際發生的是它似乎只在讀取套接字處將 3 個字節全部設置為 0。

Authenticate 方法執行以下操作。 服務器端發送1個字節的數據(0-85),客戶端接收,將其視為一個int,乘以3,然后將一個字節發送回服務器。 服務器檢查該值,並將另一個字節發送回設置為 1。

所有這些似乎都可以正常工作,但是客戶端在身份驗證后發送的數據一起似乎沒有被接收到,只有 3 個字節設置為 0。

我希望套接字在程序的生命周期內保持打開狀態,因此我無法處理流,因為這也會處理套接字。

這是客戶端和服務器的完整代碼,希望有人能看到我的錯誤,或者我遺漏的問題。

為簡潔起見,該代碼有意不進行錯誤檢查,並且只是顯示問題的基礎。

請注意,如果兩個 Authenticate 方法都簡單地返回 true,那么代碼的工作方式正是我所期望的。

服務器。

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];
            }
        }
    }

客戶

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

所以正如我所懷疑的,問題出在客戶端的 Authenticate 方法中。 我發送的是 int 而不是單個字節。 有問題的代碼行是。

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

這應該是。

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

感謝 jdweng 發現錯誤。

PS,感謝投票者對您的關注,請接受我的誠摯遺憾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM