zoukankan      html  css  js  c++  java
  • 用TCP/IP实现自己简单的应用程序协议:其余部分(包括完整代码)

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

    点击下载完整源码:

    客户端的调用

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

    }
    }

    运行结果:

  • 相关阅读:
    Scrapy 概览笔记
    Python 依赖版本控制 (requirements.txt 文件生成和使用)
    Python 虚拟空间的使用
    macOS 所有版本 JDK 安装指南 (with Homebrew)
    鉴权那些事
    Java 位运算符和 int 类型的实现
    ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门
    如何做好一次知识或技术分享
    ASP.NET Core 入门教程 4、ASP.NET Core MVC控制器入门
    ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门
  • 原文地址:https://www.cnblogs.com/lwzz/p/2138688.html
Copyright © 2011-2022 走看看