[转载]用TCP/IP实现自己简单的应用程序协议:其余部分

[转载]用TCP/IP实现自己简单的应用程序协议:其余部分 – 浪雪 – 博客园.

接着上次用TCP/IP实现自己简单的应用程序协议:成帧器部分,现在把接下来的部分也说完

代码下载:

http://download.csdn.net/source/3519903

客户端的调用

    public class VoteClientTCP {

      public static int CANDIDATEID = 888;//随便写了一个      

      public static void Main(String[] args) {

        int port = 5555;
        IPEndPoint ipep = new IPEndPoint(GetLocalhostIPv4Addresses().First(), port);

        Socket sock = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);
        try
        {
            sock.Connect(ipep);
        }
        catch (SocketException e)
        {
            Console.WriteLine("Can not connect {0} ,reason:{1},NativeErrorCode:{2},SocketErrorCode:{3}", ipep.Address, e.Message, e.NativeErrorCode, e.SocketErrorCode);
            Console.ReadKey();
            return;
        }

        IVoteMsgCoder coder = new VoteMsgTextCoder();

        IFramer framer = new LengthFramer(sock);

        VoteMsg msg = new VoteMsg(true, false, CANDIDATEID, 1);
        byte[] encodedMsg = coder.toWire(msg);

        // 发送查询
        Console.WriteLine("Sending Inquiry (" + encodedMsg.Length + " bytes): ");
        framer.frameMsg(encodedMsg);

        // 投第一票给候选人888
        msg.IsInquiry = false;
        encodedMsg = coder.toWire(msg);
        Console.WriteLine("Sending Vote (" + encodedMsg.Length + " bytes): ");
        framer.frameMsg(encodedMsg);

        // 投第二票给候选人888
        msg.IsInquiry = false;
        encodedMsg = coder.toWire(msg);
        Console.WriteLine("Sending Vote (" + encodedMsg.Length + " bytes): ");
        framer.frameMsg(encodedMsg);

        // 再次查询
        msg.IsInquiry = true;
        encodedMsg = coder.toWire(msg);
        Console.WriteLine("Sending Inquiry (" + encodedMsg.Length + " bytes): ");
        framer.frameMsg(encodedMsg);
        
        encodedMsg = framer.nextMsg();
        msg = coder.fromWire(encodedMsg);
        Console.WriteLine("Received Response (" + encodedMsg.Length
                   + " bytes): ");
        Console.WriteLine(msg);


        msg = coder.fromWire(framer.nextMsg());
        Console.WriteLine("Received Response (" + encodedMsg.Length
               + " bytes): ");
        Console.WriteLine(msg);

        msg = coder.fromWire(framer.nextMsg());
        Console.WriteLine("Received Response (" + encodedMsg.Length
               + " bytes): ");
        Console.WriteLine(msg);

        msg = coder.fromWire(framer.nextMsg());
        Console.WriteLine("Received Response (" + encodedMsg.Length
               + " bytes): ");
        Console.WriteLine(msg);

        sock.Shutdown(SocketShutdown.Both);
        sock.Close();
        Console.ReadLine();
      }

    //辅助方法
      public static IPAddress[] GetLocalhostIPv4Addresses()
      {
          IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
          List<IPAddress> list = new List<IPAddress>();
          foreach (IPAddress address in hostEntry.AddressList)
          {
              if (address.AddressFamily == AddressFamily.InterNetwork)
              {
                  list.Add(address);
              }
          }
          return list.ToArray();
      }

    }

服务端接收并返回数据:

    public class VoteServerTCP {

      public static void Main(String[] args){

        int port = 5555;

        Socket servSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );;
        //编码对象
        IVoteMsgCoder coder = new VoteMsgTextCoder();
          //服务对象
        VoteService service = new VoteService();
        //创建IP终结点
        IPAddress localAddress = AddressHelper.GetLocalhostIPv4Addresses().First();        
        IPEndPoint ipep = new IPEndPoint(localAddress, port);

        servSock.Bind(ipep);
        servSock.Listen(1);

        while (true) {
          Socket clntSock = servSock.Accept();
          Console.WriteLine("Handling client at " + clntSock.AddressFamily);

          IFramer framer = new LengthFramer(clntSock);
          try {
            byte[] req;
            while ((req = framer.nextMsg()) != null) { 
              Console.WriteLine("Received message (" + req.Length + " bytes)");
              VoteMsg responseMsg = service.handleRequest(coder.fromWire(req));
                //发回反馈消息
              framer.frameMsg(coder.toWire(responseMsg));
            }
          } catch (SocketException soe) {
              //比如说客户端提发送多条消息,又在全部接收前关闭socket时就会引发此类异常。
            Console.WriteLine("Error handling client: " + soe.Message);
          } finally {
            Console.WriteLine("Closing connection");
            clntSock.Close();
          }
        }
      }
    }

对字符串编码的简单实现

    public class VoteMsgTextCoder : IVoteMsgCoder
    {
        // 下面是需要进行编码的字段
        public static readonly String MAGIC = "Voting";
        public static readonly String VOTESTR = "v";
        public static readonly String INQSTR = "i";
        public static readonly String RESPONSESTR = "R";

        public static readonly String DELIMSTR = " ";
        UTF8Encoding encoder = null;


        public static readonly int MAX_WIRE_LENGTH = 2000;


        public VoteMsgTextCoder()
        {
            encoder = new UTF8Encoding();
        }



        public byte[] toWire(VoteMsg msg)
        {
            String msgString = MAGIC + DELIMSTR + (msg.IsInquiry ? INQSTR : VOTESTR)
                + DELIMSTR + (msg.IsResponse ? RESPONSESTR + DELIMSTR : "")
                + msg.CandidateID.ToString() + DELIMSTR
                + msg.VoteCount.ToString();
            byte[] data = encoder.GetBytes(msgString);
            return data;
        }

        public VoteMsg fromWire(byte[] message)
        {

            bool isInquiry;
            bool isResponse;
            int candidateID;
            long voteCount;
            string token;

            string StringSentByClient = Encoding.UTF8.GetString(message);
            string[] fields = StringSentByClient.Split(new char[] { ' ' });

            try
            {
                token = fields[0];
                if (!token.Equals(MAGIC))
                {
                    throw new IOException("Bad magic string: " + token);
                }
                token = fields[1];
                if (token.Equals(VOTESTR))
                {
                    isInquiry = false;
                }
                else if (!token.Equals(INQSTR))
                {
                    throw new IOException("Bad vote/inq indicator: " + token);
                }
                else
                {
                    isInquiry = true;
                }

                token = fields[2];
                if (token.Equals(RESPONSESTR))
                {
                    isResponse = true;
                    token = fields[3];
                }
                else
                {
                    isResponse = false;
                }

                candidateID = int.Parse(token);
                if (isResponse)
                {
                    token = fields[4];
                    voteCount = long.Parse(token);
                }
                else
                {
                    voteCount = 0;
                }
            }
            catch (IOException ioe)
            {
                throw new IOException("Parse error...");
            }

            return new VoteMsg(isInquiry, isResponse, candidateID, voteCount);

        }
    }

运行结果:

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏