| 0 | 1 | 2 | 3 |
|------------------------------------------------|
| Header Version | Message Type |
|------------------------------------------------|
| Message Length |
|------------------------------------------------|
| 0 | 1 | 2 | 3 |
|------------------------------------------------|
|00000000 | 00000001 |00000000 |00000000 |
|------------------------------------------------|
| 0000000000000000000000000000000 |
|------------------------------------------------|
这是我写的一个模仿这个数据结构的类。我担心的是转换为无符号的整数。我想通过SSL发送此数据包。如果这是正确的,不太确定。任何帮助将不胜感激。
public abstract class Message {
protected static final short NULL_MESSAGE_TYPE = 0;
protected short _headerVersion;
protected short _messageType;
protected int _messageLength;
protected Message (short headerVersion, short messageType, int messageLength) {
_headerVersion = headerVersion;
_messageType = messageType;
_messageLength = messageLength;
}
public short getHeaderVersion() {
return _headerVersion;
}
public short getMessageType() {
return _messageType;
}
public int getMessageLength() {
return _messageLength;
}
protected static short getHeaderVersion(byte[] bytes) throws Exception {
return getUnsignedInt16(bytes, 0, 1);
}
protected static short getMessageType(byte[] bytes) throws Exception {
return getUnsignedInt16(bytes, 2, 3);
}
protected static int getMessageLength(byte[] bytes) throws Exception {
return getUnsignedInt32(bytes, 4, 7);
}
protected static short getUnsignedInt16(byte[] bytes, int beginPosition, int endPosition) throws Exception {
short value = 0;
byte shiftValue = 8;
if (endPosition - beginPosition > 1)
throw new Exception("Invalid beginPosition and endPosition");
for(int position = beginPosition; position <= endPosition; position++) {
value += unsignedByteToShort(bytes[position]) << shiftValue;
shiftValue -= 8;
}
return value;
}
protected static int getUnsignedInt32(byte[] bytes, int beginPosition, int endPosition) throws Exception {
int value = 0;
byte shiftValue = 24;
if ( endPosition - beginPosition > 3)
throw new Exception("Invalid beginPosition and endPosition");
for(int position = beginPosition; position <= endPosition; position++) {
value += unsignedByteToInt( bytes[position] ) << shiftValue;
shiftValue -= 8;
}
return value;
}
// Get an unsigned byte to a short
protected static short unsignedByteToShort(byte b) {
return (short) (b & 0xFF);
}
//Get an unsigned byte to an int
protected static int unsignedByteToInt(byte b) {
return (int) (b & 0xFF);
}
public static MessageTypes getType(byte[] bytes) throws Exception {
short headerVersion = getHeaderVersion(bytes);
short messageType = getMessageType(bytes);
if (headerVersion != 1)
throw new Exception("Unsupported Version");
if(messageType == NULL_MESSAGE_TYPE) {
return MessageTypes.NULL_MESSAGE_TYPE;
} else {
return MessageTypes.UNKNOWN;
}
}
public abstract byte[] getBytes();
}
派生类:
public class NullMessage extends Message {
public NullMessage() {
super((short) 1, NULL_MESSAGE_TYPE, 0); //Using a short for 16 bits unsigned byte
}
public byte[] getBytes() {
byte[] bytes = new byte[8];
// HEADER VERSION
bytes[0] = (byte) (_headerVersion >>> 8); //Shifts a zero to the leftmost position
bytes[1] = (byte) _headerVersion;
//MESSAGE TYPE
bytes[2] = (byte)(_messageType >>> 8);
bytes[3] = (byte) _messageType;
//MESSAGE LENGTH
bytes[4] = (byte)(_messageLength >>> 24);
bytes[5] = (byte)(_messageLength >>> 16);
bytes[6] = (byte)(_messageLength >>> 8);
bytes[7] = (byte)_messageLength;
return bytes;
}
}
测试在
下面public class Client {
private static String ip = 1.2.3.4";
private static int DEFAULT_PORT= 8888;
private static File keyStore = new File(
"\\Program Files\\Java\\jdk1.8.0_51\\bin\\truststore.jks");
//this is the password for the keystore
private static String keyStorePassword = "password";
private static SSLSocketFactory getSSLSocketFactory() throws IOException,
GeneralSecurityException {
// Call getTrustManagers to get suitable trust managers
TrustManager[] tms = getTrustManagers();
// Call getKeyManagers to get suitable key managers
KeyManager[] kms = getKeyManagers();
// Now construct a SSLContext using these KeyManagers. We
// specify a null TrustManager and SecureRandom, indicating that the
// defaults should be used.
SSLContext context = SSLContext.getInstance("SSL");
context.init(kms, tms, null);
// Finally, we get a SocketFactory, and pass it to SimpleSSLClient.
SSLSocketFactory ssf = context.getSocketFactory();
return ssf;
}
private static TrustManager[] getTrustManagers() throws IOException,
GeneralSecurityException {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) {
}
} };
return trustAllCerts;
}
private static KeyManager[] getKeyManagers() throws IOException,
GeneralSecurityException {
// First, get the default KeyManagerFactory.
String alg = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmFact = KeyManagerFactory.getInstance(alg);
// Next, set up the KeyStore to use. We need to load the file into
// a KeyStore instance.
FileInputStream fis = new FileInputStream(keyStore);
KeyStore ks = KeyStore.getInstance("jks");
ks.load(fis, keyStorePassword.toCharArray());
fis.close();
// Now we initialize the TrustManagerFactory with this KeyStore
kmFact.init(ks, keyStorePassword.toCharArray());
// And now get the TrustManagers
KeyManager[] kms = kmFact.getKeyManagers();
return kms;
}
public static void main(String[] args) throws InterruptedException, Exception {
try {
SSLSocketFactory sslSocketFactory = getSSLSocketFactory();
SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(
ip, DEFAULT_PORT);
socket.setSoTimeout(99999999);
System.out.println("Connecting to "
+ socket.getRemoteSocketAddress().toString() + " : "
+ socket.getPort());
System.out.println("Is Connected? " + socket.isConnected());
socket.startHandshake();
System.out.println("We Made it!!");
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
DataOutputStream dos = new DataOutputStream(out);
DataInputStream dis = new DataInputStream(in);
//RequestMessage requestMessage = new RequestMessage((int)(System.currentTimeMillis() / 100), (short)1);
NullMessage nullMessage = new NullMessage();
byte[] bytes = nullMessage.getBytes();
dos.writeInt(bytes.length);
if(bytes.length > 0) {
dos.write(bytes, 0, bytes.length);
}
socket.close();