找出TCP服务器是否已发送数据

时间:2017-03-31 19:20:27

标签: c# tcp

  1. 我有一个TCP服务器,它只为客户端发送给服务器的某些消息将数据写回客户端。
  2. 它基本上是一个基于命令的服务器,服务器只为某些命令响应字符串,否则不会将任何内容发送回客户端。

  3. 下面给出的代码是一种方法,它假定如果服务器发送了任何数据,它会将其显示为“MESSAGE FROM SERVER”,附加了已发送的数据。

        class TcpEchoClient
        {
        static void Main(string[] args)
        {
        Console.WriteLine("Starting echo client...");
    
    
                string ipaddress = "127.0.0.1";
                TcpClient client = null;
                NetworkStream netstream = null;
    
                try
                {
    
                    client = new TcpClient(ipaddress,1000);
                    netstream = client.GetStream();
    
                }
                catch
                {
                    Console.ReadKey();
                    Environment.Exit(0);
                }
    
    
                while(true)
                {
                    Console.WriteLine("Message :  ");
                    string t = Console.ReadLine();
                    string readdata = null;
                    Console.WriteLine("\n");
    
    
                    if (write(t,netstream))
                    {
                        Console.WriteLine("Message sent.");
    
                        if (client.Available!=0)
                        {
                            readdata = read(netstream);
                            Console.WriteLine("MESSAGE FROM SERVER : "+readdata);
                        }
    
    
                    }
                    else
                    {
                        Console.WriteLine("Unable to send message.");
                    }
                }
    
    
            }
    
            static bool write(string dat, NetworkStream stream) 
            {
    
                try
                {
    
                    StreamWriter writer = new StreamWriter(stream) { AutoFlush = true };
    
    
                    try{writer.WriteLine(dat);}
                    catch (IOException){return false;}
    
                    if (SHAHash(dat, "DATA") != SHAHash(read(stream), "DATA"))
                        return false;
                }catch (InvalidOperationException){return false;}
    
    
                return true;        
            }
    
            static string read(NetworkStream stream)
            {
    
                StreamReader reader = new StreamReader(stream);
    
                string readdata = null;
    
                try
                {
                    readdata = reader.ReadLine();
                    reader.BaseStream.Flush();
                }
                catch(IOException)
                {
                    return null;
                }
    
                return readdata;
            }
    }
    
  4. 此帖子中未显示SHAHash函数。它的格式是SHAHash(消息,盐)。

    面临的问题是服务器发送的消息并不总是由客户端读取。有时,服务器发送的数据会显示客户端控制台,有时则不会。

    我应该对上面的代码进行哪些更正,这样我才能在发送数据时从服务器读取数据。也就是说,只有当服务器向客户端发送一些数据时才需要执行以下代码,否则不应该执行它。

    readdata = read(netstream);
    Console.WriteLine("MESSAGE FROM SERVER : "+readdata);
    

2 个答案:

答案 0 :(得分:0)

使用冲洗或自动冲洗时要谨慎。有时它会在发送/接收操作之前执行......但这通常在使用线程时发生。

我的第一个提示是流阅读器/编写器没有被正确破坏。尝试将它们打包成使用声明。

答案 1 :(得分:0)

TCP不同步,因此您无法写入数据并希望响应立即可用。当您执行以下检查时

if (client.Available!=0)

无法保证服务器尚未发送任何响应。您需要继续检查,直到有可用数据或异步读取数据

我会使用NetworkStream.BeginRead和callbacks来获取服务器响应

class StreamData
{

    public NetworkStream netstream;

    public byte[] myReadBuffer;
}


class TcpEchoClient
{

    static void Main(string[] args)
    {
        Console.WriteLine("Starting echo client...");

        string ipaddress = "127.0.0.1";
        TcpClient client = null;
        NetworkStream netstream = null;

        try
        {
            client = new TcpClient(ipaddress, 13000);
            netstream = client.GetStream();
        }
        catch
        {
            Console.ReadKey();
            Environment.Exit(0);
        }
        var streamData = new StreamData
        {
            netstream = netstream,
            myReadBuffer = new byte[1024],
        };

        netstream.BeginRead(streamData.myReadBuffer, 0, streamData.myReadBuffer.Length,
                                                   new AsyncCallback(myReadCallBack),
                                                   streamData);

        while (true)
        {
            Console.WriteLine("Message :  ");
            string t = Console.ReadLine();
            Console.WriteLine("\n");

            if (write(t, netstream))
            {
                Console.WriteLine("Message sent.");
            }
            else
            {
                Console.WriteLine("Unable to send message.");
            }
        }
    }

    static void myReadCallBack(IAsyncResult ar)
    {
        var streamData = (StreamData)ar.AsyncState;
        int bytesRead = streamData.netstream.EndRead(ar);
        var readdata = Encoding.ASCII.GetString(streamData.myReadBuffer, 0, bytesRead);
        //Be aware that this might not be the complete message depending on the size of the message and the buffer size
        Console.WriteLine("You received the following message : " + readdata);

        //Start waiting for more data
        streamData.netstream.BeginRead(streamData.myReadBuffer, 0, streamData.myReadBuffer.Length,
                                                   new AsyncCallback(myReadCallBack),
                                                   streamData);
    }

    static bool write(string dat, NetworkStream stream)
    {
        try
        {
            StreamWriter writer = new StreamWriter(stream) { AutoFlush = true };

            try { writer.WriteLine(dat); }
            catch (IOException) { return false; }

            //if (SHAHash(dat, "DATA") != SHAHash(read(stream), "DATA"))
            //    return false;
        }
        catch (InvalidOperationException) { return false; }

        return true;
    }


}