public boolean send(Socket socket) { assert (socket != null); ZMsg msg = new ZMsg(); // If we're sending to a ROUTER, send the routingId first if (socket.getType() == ZMQ.ROUTER) { msg.add(routingId); } int frameSize = 2 + 1; // Signature and message ID switch (id) { case LOG: { // sequence is a 2-byte integer frameSize += 2; // version is a 2-byte integer frameSize += 2; // level is a 1-byte integer frameSize += 1; // event is a 1-byte integer frameSize += 1; // node is a 2-byte integer frameSize += 2; // peer is a 2-byte integer frameSize += 2; // time is a 8-byte integer frameSize += 8; // host is a string with 1-byte length frameSize++; frameSize += (host != null) ? host.length() : 0; // data is a long string with 4-byte length frameSize += 4; frameSize += (data != null) ? data.length() : 0; } break; case STRUCTURES: { // sequence is a 2-byte integer frameSize += 2; // aliases is an array of strings frameSize += 4; if (aliases != null) { for (String value : aliases) { frameSize += 4; frameSize += value.length(); } } // headers is an array of key=value strings frameSize += 4; if (headers != null) { headersBytes = 0; for (Map.Entry<String, String> entry : headers.entrySet()) { headersBytes += 1 + entry.getKey().length(); headersBytes += 4 + entry.getValue().length(); } frameSize += headersBytes; } } break; case BINARY: { // sequence is a 2-byte integer frameSize += 2; // flags is a block of 4 bytes frameSize += 4; // public_key is a chunk with 4-byte length frameSize += 4; frameSize += (public_key != null) ? public_key.length : 0; // identifier is uuid with 16-byte length frameSize += 16; } break; case TYPES: { // sequence is a 2-byte integer frameSize += 2; // client_forename is a string with 1-byte length frameSize++; frameSize += (client_forename != null) ? client_forename.length() : 0; // client_surname is a string with 1-byte length frameSize++; frameSize += (client_surname != null) ? client_surname.length() : 0; // client_mobile is a string with 1-byte length frameSize++; frameSize += (client_mobile != null) ? client_mobile.length() : 0; // client_email is a string with 1-byte length frameSize++; frameSize += (client_email != null) ? client_email.length() : 0; // supplier_forename is a string with 1-byte length frameSize++; frameSize += (supplier_forename != null) ? supplier_forename.length() : 0; // supplier_surname is a string with 1-byte length frameSize++; frameSize += (supplier_surname != null) ? supplier_surname.length() : 0; // supplier_mobile is a string with 1-byte length frameSize++; frameSize += (supplier_mobile != null) ? supplier_mobile.length() : 0; // supplier_email is a string with 1-byte length frameSize++; frameSize += (supplier_email != null) ? supplier_email.length() : 0; } break; default: System.out.printf("E: bad message type '%d', not sent\n", id); assert (false); } // Now serialize message into the frame ZFrame frame = new ZFrame(new byte[frameSize]); needle = ByteBuffer.wrap(frame.getData()); int frameFlags = 0; putNumber2(0xAAA0 | 0); putNumber1((byte) id); switch (id) { case LOG: { putNumber2(sequence); putNumber2(3); putNumber1(level); putNumber1(event); putNumber2(node); putNumber2(peer); putNumber8(time); if (host != null) putString(host); else putNumber1((byte) 0); // Empty string if (data != null) putLongString(data); else putNumber4(0); // Empty string } break; case STRUCTURES: { putNumber2(sequence); if (aliases != null) { putNumber4(aliases.size()); for (String value : aliases) { putLongString(value); } } else putNumber4(0); // Empty string array if (headers != null) { putNumber4(headers.size()); for (Map.Entry<String, String> entry : headers.entrySet()) { putString(entry.getKey()); putLongString(entry.getValue()); } } else putNumber4(0); // Empty hash } break; case BINARY: { putNumber2(sequence); putBlock(flags, 4); if (public_key != null) { putNumber4(public_key.length); needle.put(public_key, 0, public_key.length); } else { putNumber4(0); } if (identifier != null) { ByteBuffer bb = ByteBuffer.wrap(new byte[16]); bb.putLong(identifier.getMostSignificantBits()); bb.putLong(identifier.getLeastSignificantBits()); needle.put(bb.array()); } else { needle.put(new byte[16]); // Empty Chunk } } break; case TYPES: { putNumber2(sequence); if (client_forename != null) putString(client_forename); else putNumber1((byte) 0); // Empty string if (client_surname != null) putString(client_surname); else putNumber1((byte) 0); // Empty string if (client_mobile != null) putString(client_mobile); else putNumber1((byte) 0); // Empty string if (client_email != null) putString(client_email); else putNumber1((byte) 0); // Empty string if (supplier_forename != null) putString(supplier_forename); else putNumber1((byte) 0); // Empty string if (supplier_surname != null) putString(supplier_surname); else putNumber1((byte) 0); // Empty string if (supplier_mobile != null) putString(supplier_mobile); else putNumber1((byte) 0); // Empty string if (supplier_email != null) putString(supplier_email); else putNumber1((byte) 0); // Empty string } break; } // Now send the data frame msg.add(frame); // Now send any frame fields, in order switch (id) { case BINARY: { // If address isn't set, send an empty frame if (address == null) address = new ZFrame("".getBytes()); msg.add(address); } break; } switch (id) { case BINARY: { if (content == null) content = new ZMsg(); for (ZFrame contentPart : content) { msg.add(contentPart); } } break; } // Destroy ZprotoExample object msg.send(socket); destroy(); return true; }
public static ZprotoExample recv(Socket input) { assert (input != null); ZprotoExample self = new ZprotoExample(0); ZFrame frame = null; try { // Read valid message frame from socket; we loop over any // garbage data we might receive from badly-connected peers while (true) { // If we're reading from a ROUTER socket, get routingId if (input.getType() == ZMQ.ROUTER) { self.routingId = ZFrame.recvFrame(input); if (self.routingId == null) return null; // Interrupted if (!self.routingId.hasData()) return null; // Empty Frame (eg recv-timeout) if (!input.hasReceiveMore()) throw new IllegalArgumentException(); } // Read and parse command in frame frame = ZFrame.recvFrame(input); if (frame == null) return null; // Interrupted // Get and check protocol signature self.needle = ByteBuffer.wrap(frame.getData()); int signature = self.getNumber2(); if (signature == (0xAAA0 | 0)) break; // Valid signature // Protocol assertion, drop message while (input.hasReceiveMore()) { frame.destroy(); frame = ZFrame.recvFrame(input); } frame.destroy(); } // Get message id, which is first byte in frame self.id = self.getNumber1(); int listSize; int hashSize; switch (self.id) { case LOG: { self.sequence = self.getNumber2(); self.version = self.getNumber2(); if (self.version != 3) throw new IllegalArgumentException(); self.level = self.getNumber1(); self.event = self.getNumber1(); self.node = self.getNumber2(); self.peer = self.getNumber2(); self.time = self.getNumber8(); self.host = self.getString(); self.data = self.getLongString(); } break; case STRUCTURES: { self.sequence = self.getNumber2(); listSize = (int) self.getNumber4(); self.aliases = new ArrayList<String>(); while (listSize-- > 0) { String string = self.getLongString(); self.aliases.add(string); } hashSize = (int) self.getNumber4(); self.headers = new HashMap<String, String>(); while (hashSize-- > 0) { String key = self.getString(); String value = self.getLongString(); self.headers.put(key, value); } } break; case BINARY: { self.sequence = self.getNumber2(); self.flags = self.getBlock(4); self.public_key = self.getBlock((int) self.getNumber4()); ByteBuffer bbIdentifier = ByteBuffer.wrap(self.getBlock(16)); self.identifier = new UUID(bbIdentifier.getLong(), bbIdentifier.getLong()); // Get next frame, leave current untouched if (!input.hasReceiveMore()) throw new IllegalArgumentException(); self.address = ZFrame.recvFrame(input); self.content = new ZMsg(); if (input.hasReceiveMore()) self.content.add(ZFrame.recvFrame(input)); } break; case TYPES: { self.sequence = self.getNumber2(); self.client_forename = self.getString(); self.client_surname = self.getString(); self.client_mobile = self.getString(); self.client_email = self.getString(); self.supplier_forename = self.getString(); self.supplier_surname = self.getString(); self.supplier_mobile = self.getString(); self.supplier_email = self.getString(); } break; default: throw new IllegalArgumentException(); } return self; } catch (Exception e) { // Error returns System.out.printf("E: malformed message '%d'\n", self.id); self.destroy(); return null; } finally { if (frame != null) frame.destroy(); } }