首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于TCP的通信系统中的消息发送

基于TCP的通信系统中的消息发送
EN

Code Review用户
提问于 2017-10-06 22:43:44
回答 1查看 17.4K关注 0票数 10

我正在开发一个基于TCP的通信系统。

我编写了一个用于发送Textmessages和远程打开MessageBox的工作函数。我想知道这段代码有多优雅,我可以如何改进它,因为在我看来,它似乎很混乱。

客户端:

代码语言:javascript
复制
private void btnSend_Click(object sender, EventArgs e)
{
    NetworkStream stream = client.GetStream();

    BinaryWriter w = new BinaryWriter(stream);

        byte[] msg = new byte[4096];
        msg = Encoding.ASCII.GetBytes("%" + txtMsg.Text + "&");

        w.Write(msg, 0, msg.Length);

}

private void btnMsgBox_Click(object sender, EventArgs e)
{
    NetworkStream stream = client.GetStream();

    byte[] msg = new byte[4096];          

    msg = Encoding.ASCII.GetBytes("%DisplayRemoteMessageBox&" + txtMsg.Text + "#");
    stream.Write(msg, 0, msg.Length);            
}

服务器:

代码语言:javascript
复制
while(true)
{
    while(client.Connected)
    {
        byte[] msg = new byte[4096];
        var count = stream.Read(msg, 0, msg.Length);

        string returnData = Encoding.ASCII.GetString(msg, 0, count);

        string command = returnData.Substring((returnData.IndexOf("%") + 1), (returnData.IndexOf("&") -1));


        switch(command)
        { 
        case "DisplayRemoteMessageBox":
                returnData = returnData.Replace("%DisplayRemoteMessageBox", "");
                int startInd = returnData.IndexOf("&");
                int len = returnData.IndexOf("#");                            

                returnData = returnData.Substring((startInd + 1), (len - 1));
                MessageBox((IntPtr)0, returnData, "TestBox", 0);
                 break;
        case "":                            
                client.Client.Disconnect(true);                        
                Console.WriteLine("User disconnected");
                 break;
        default:
                returnData = returnData.Substring(1, (returnData.Length - 2));
                Console.WriteLine(returnData);
                 break;
        }                 
    }
}
EN

回答 1

Code Review用户

发布于 2017-10-07 02:18:41

使用适当的名称

  • returnData是什么?味精是什么?

不要覆盖相同的变量:

代码语言:javascript
复制
 byte[] msg = new byte[4096];
            msg = Encoding.ASCII.GetBytes("%" + txtMsg.Text + "&");

// You could simply do this instead:
   byte[] msg = Encoding.ASCII.GetBytes("%" + txtMsg.Text + "&");

// Also you’re reusing variables and overwriting. I don’t recommend this type of thing:

  string returnData = Encoding.ASCII.GetString(msg, 0, count);
            switch(command)
            { 
            case "DisplayRemoteMessageBox":
                    returnData = returnData.Replace("%DisplayRemoteMessageBox", ""); // don’t reset the returnData variable
                    returnData = returnData.Substring((startInd + 1), (len - 1));
            case "":                            
            default:
                    returnData = returnData.Substring(1, (returnData.Length - 2));
            }     

个人而言,我不会用您的代码更改任何东西.

但是如果你想做更多的事情,那么这里有一些想法。这是一个很好的练习--我会把它发到这里,否则看起来是浪费--但我认为它不必要地复杂了代码。保持您的代码原样。

代码语言:javascript
复制
internal class Program
{
    private static void Main(string[] args)
    {
    }

    #region Client Classes

    private ClientImplementation client = new ClientImplementation();
    private TextImplementation txtMsg = new TextImplementation();

    private void btnSend_Click_GiveAppropriateName1(object sender, EventArgs e)
    {
        // could use use a factory to get the writer
        Writer writer = new StandardWriter(client.GetStream(), txtMsg);
        writer.Write();
    }

    private void btnSend_ClickGiveAppropriateName2(object sender, EventArgs e)
    {
        Writer writer = new RemoteMessageBoxWriter(client.GetStream(), txtMsg);
        writer.Write();
    }

    public abstract class Writer
    {
        private BinaryWriter w;
        protected byte[] msg;
        protected TextImplementation txtMsg;

        public Writer(NetworkStream stream, TextImplementation txtMsg)
        {
            this.w = new BinaryWriter(stream);
            this.txtMsg = txtMsg;
            this.msg = GetBytes();
        }

        protected abstract byte[] GetBytes();

        public void Write()
        {
            w.Write(msg, 0, msg.Length);
        }
    }

    public class StandardWriter : Writer
    {
        public StandardWriter(NetworkStream stream, TextImplementation txtMsg)
            : base(stream, txtMsg)
        {
        }

        protected override byte[] GetBytes()
        {
            return Encoding.ASCII.GetBytes("%" + txtMsg.Text + "&");
        }
    }

    public class RemoteMessageBoxWriter : Writer
    {
        public RemoteMessageBoxWriter(NetworkStream stream, TextImplementation txtMsg)
            : base(stream, txtMsg)
        {
        }

        protected override byte[] GetBytes()
        {
            return Encoding.ASCII.GetBytes("%DisplayRemoteMessageBox&" + txtMsg.Text + "#");
        }
    }

    #endregion Client Classes

    #region Server Code

    public void Server()
    {
        while (true)
        {
            while (client.Connected)
            {
                HandleCommand command = new HandleCommandFactory().ReturnHandle(client.GetStream());
                command.DisplayData();
            }
        }
    }

    public class HandleCommandFactory
    {
        private NetworkStream stream;

        public HandleCommand ReturnHandle(NetworkStream stream)
        {
            this.stream = stream;
            string command = GetCommand(stream);

            switch (command)
            {
                case "DisplayRemoteMessageBox":
                    return new DisplayRemoteMsgBox();

                case "":
                    return new Disconnect();

                default:
                    return new Default();
            }
        }

        private string GetCommand(NetworkStream stream)
        {
            byte[] msg = new byte[4096];
            var count = this.stream.Read(msg, 0, msg.Length);
            string returnData = Encoding.ASCII.GetString(msg, 0, count);

            return returnData;
        }
    }

    abstract public class HandleCommand
    {
        protected string returnData;
        protected ClientImplementation client;

        abstract public void DisplayData();

        public HandleCommand()
        {
        }

        public HandleCommand(string returnData, ClientImplementation client)
        {
            this.returnData = returnData;
            this.client = client;
        }
    }

    public class Default : HandleCommand
    {
        public override void DisplayData()
        {
            string formattedData = returnData.Substring(1, (returnData.Length - 2));
            Console.WriteLine(formattedData);
        }
    }

    public class Disconnect : HandleCommand
    {
        public override void DisplayData()
        {
            client.Client.Disconnect(true);
            Console.WriteLine("User disconnected");
        }
    }

    public class DisplayRemoteMsgBox : HandleCommand
    {
        public override void DisplayData()
        {
            returnData = returnData.Replace("%DisplayRemoteMessageBox", "");
            int startInd = returnData.IndexOf("&");
            int len = returnData.IndexOf("#");

            string formattedData = returnData.Substring((startInd + 1), (len - 1));
            MessageBox((IntPtr)0, formattedData, "TestBox", 0);
        }

        private void MessageBox(IntPtr intPtr, string returnData, string p1, int p2)
        {
            throw new NotImplementedException();
        }
    }

    #endregion Server Code

    #region Additions just to make it compile

    public class ClientImplementation
    {
        public NetworkStream GetStream()
        {
            return new NetworkStream(GetSocket("blah", 0));
        }

        public bool Connected
        {
            get { return true; }
        }
    }

    public class TextImplementation
    {
        public string Text { get; set; }
    }

    private static Socket GetSocket(string server, int port)
    {
        Socket s = null;
        IPHostEntry hostEntry = null;

        // Get host related information.
        hostEntry = Dns.GetHostEntry(server);

        // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
        // an exception that occurs when the host IP Address is not compatible with the address family
        // (typical in the IPv6 case).
        foreach (IPAddress address in hostEntry.AddressList)
        {
            IPEndPoint ipe = new IPEndPoint(address, port);
            Socket tempSocket =
                new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            tempSocket.Connect(ipe);

            if (tempSocket.Connected)
            {
                s = tempSocket;
                break;
            }
            else
            {
                continue;
            }
        }
        return s;
    }

    #endregion Additions just to make it compile
}
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/177358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档