Udp投票通信例子

用到的文本编码:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class VoteMsgTextCoder implements VoteMsgCoder {
  /*
   * Wire Format "VOTEPROTO" <"v" | "i"> [<RESPFLAG>] <CANDIDATE> [<VOTECNT>]
   * Charset is fixed by the wire format.
   */

    // Manifest constants for encoding
    public static final String MAGIC = "Voting";
    public static final String VOTESTR = "v";
    public static final String INQSTR = "i";
    public static final String RESPONSESTR = "R";
    public static final String CHARSETNAME = "US-ASCII";
    public static final String DELIMSTR = " ";
    public static final int MAX_WIRE_LENGTH = 2000;//指定传输的最大字节长度.如果超过了这个长度会造成消息被截断,接收信息就不全.
    public byte[] toWire(VoteMsg msg) throws IOException {
        String msgString = MAGIC + DELIMSTR + (msg.isInquiry() ? INQSTR : VOTESTR)
                + DELIMSTR + (msg.isResponse() ? RESPONSESTR + DELIMSTR : "")
                + Integer.toString(msg.getCandidateID()) + DELIMSTR
                + Long.toString(msg.getVoteCount());
        byte data[] = msgString.getBytes(CHARSETNAME);
        return data;
    }
    public VoteMsg fromWire(byte[] message) throws IOException {
        ByteArrayInputStream msgStream = new ByteArrayInputStream(message);
        //Scanner默认是使用空格作为定界符
        Scanner s = new Scanner(new InputStreamReader(msgStream, CHARSETNAME));
        boolean isInquiry;
        boolean isResponse;
        int candidateID;
        long voteCount;
        String token;
        try {
            token = s.next();
            if (!token.equals(MAGIC)) {
                throw new IOException("Bad magic string: " + token);
            }
            token = s.next();
            if (token.equals(VOTESTR)) {
                isInquiry = false;
            } else if (!token.equals(INQSTR)) {
                throw new IOException("Bad vote/inq indicator: " + token);
            } else {
                isInquiry = true;
            }

            token = s.next();
            if (token.equals(RESPONSESTR)) {
                isResponse = true;
                token = s.next();
            } else {
                isResponse = false;
            }
            // Current token is candidateID
            // Note: isResponse now valid
            candidateID = Integer.parseInt(token);
            if (isResponse) {
                token = s.next();
                voteCount = Long.parseLong(token);
            } else {
                voteCount = 0;
            }
        } catch (IOException ioe) {
            throw new IOException("Parse error...");
        }
        return new VoteMsg(isResponse, isInquiry, candidateID, voteCount);
    }
}

一.服务端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Arrays;

public class VoteServerUDP {

    public static void main(String[] args) throws IOException {

        DatagramSocket sock = new DatagramSocket(9000); //服务端当然要指定端口
        //接收的缓冲字节码数组
        byte[] inBuffer = new byte[VoteMsgTextCoder.MAX_WIRE_LENGTH];
        //使用与客户端同样的基于文本的编码器
        VoteMsgCoder coder = new VoteMsgTextCoder();
        //与前文一样,用于处理投票请求
        VoteService service = new VoteService();

        while (true) {
            //接收端的数据报文包实例指定缓冲字节码数组与长度即可(放在这个位置很重要,需要重置缓冲区)
            DatagramPacket packet = new DatagramPacket(inBuffer, inBuffer.length);
            //进行接收(此方法是阻塞的,直到一个数据报文包已接收)
            sock.receive(packet);
            //获取实际有效的字节码
            byte[] encodedMsg = Arrays.copyOfRange(packet.getData(), 0, packet.getLength());
            System.out.println("Handling request from " + packet.getSocketAddress() + " (" + encodedMsg.length + " bytes)");

            try {
                //反将字节码转成VoteMsg实例(相当于反序列化)
                VoteMsg msg = coder.fromWire(encodedMsg);
                //处理投票业务逻辑
                msg = service.handleRequest(msg);//返回的是处理后的一个VoteMsg(包含候选人的票数等信息)
                //只需要简单重置消息数据
                packet.setData(coder.toWire(msg));
                System.out.println("Sending response (" + packet.getLength() + " bytes):");
                System.out.println(msg);
                //发送时,会将这个数据报文包原来的源主机和源端口作为目标主机和目标端口
                sock.send(packet);
            } catch (IOException ioe) {
                System.err.println("Parse error in message: " + ioe.getMessage());
            }
        }
    }
}

还有服务端处理投票请求的服务类与前文一样

二.客户端

import java.io.OutputStream;
import java.net.Socket;

public class VoteClientTCP {

    public static final int CANDIDATEID = 888;

    public static void main(String args[]) throws Exception {

        Socket sock = new Socket("127.0.0.1", 9000);
        OutputStream out = sock.getOutputStream();

        //创建一个二进制编码实例
        VoteMsgCoder coder = new VoteMsgBinCoder();
        //创建一个基于长度的成帧方法实例
        Framer framer = new LengthFramer(sock.getInputStream());

        //创建一个查询请求消息
        VoteMsg msg = new VoteMsg(false, true, CANDIDATEID, 0);
        //将消息转成字节码(相当于序列化))
        byte[] encodedMsg = coder.toWire(msg);

        System.out.println("Sending Inquiry (" + encodedMsg.length + " bytes): ");
        System.out.println(msg);
        //发送查询请求
        framer.frameMsg(encodedMsg, out);

        //改为投票请求
        msg.setInquiry(false);
        //将消息转成字节码(相当于序列化)
        encodedMsg = coder.toWire(msg);
        System.out.println("Sending Vote (" + encodedMsg.length + " bytes): ");
        //发送投票请求
        framer.frameMsg(encodedMsg, out);

        //从响应取出查询消息
        encodedMsg = framer.nextMsg();
        //转为VoteMsg实例(相当于反序列化)
        msg = coder.fromWire(encodedMsg);
        System.out.println("Received Response (" + encodedMsg.length + " bytes): ");
        System.out.println(msg);

        //从响应取出投票消息
        encodedMsg = framer.nextMsg();
        msg = coder.fromWire(encodedMsg);
        System.out.println("Received Response (" + encodedMsg.length + " bytes): ");
        System.out.println(msg);
        //关闭socket
        sock.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript的UDP通信实例中,我们可以使用`dgram`模块来实现UDP通信。首先,我们需要引入`dgram`模块: ```javascript const dgram = require('dgram'); ``` 接下来,我们可以创建一个UDP服务器,监听指定的端口: ```javascript const server = dgram.createSocket('udp4'); const PORT = 8080; server.on('listening', function () { const address = server.address(); console.log('UDP服务器正在监听' + address.address + ':' + address.port); }); server.on('message', function (message, remote) { console.log('接收到来自' + remote.address + ':' + remote.port + '的数据:' + message); }); server.bind(PORT); ``` 在这个例子中,我们创建了一个UDP服务器并绑定到8080端口。当服务器接收到UDP数据包时,会触发`message`事件,并打印出接收到的数据以及发送者的地址和端口。 接下来,我们可以创建一个UDP客户端,用于向服务器发送数据: ```javascript const client = dgram.createSocket('udp4'); const SERVER_PORT = 8080; const message = Buffer.from('Hello, Server!'); client.send(message, SERVER_PORT, 'localhost', function (error) { if (error) { console.error('发送数据包失败:' + error); } else { console.log('成功发送数据到服务器'); client.close(); } }); ``` 在这个例子中,我们创建了一个UDP客户端,并使用`send`方法向服务器发送了一条数据。在发送完成后,我们关闭了客户端的连接。 这就是一个简单的JavaScript UDP通信的实例。通过服务器和客户端之间的UDP连接,我们可以进行双向的数据传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值