📄 vpptransaction.java
字号:
/* * ==================================================================== * The Class Description * Version: 1.0.0 * Date: 11/08/2005 * Author: Xing.zhou * Function: 这个类的功能完成本系统的用户数据与pserver交互的通讯功能 * * ==================================================================== * */package vocal.comm;import java.net.Socket;import java.net.InetAddress;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;import vocal.comm.TrustAllTrustManager;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSocket;import javax.net.SocketFactory;import java.io.*;import javax.swing.JOptionPane;import javax.swing.JFrame;/** * This class is an abstraction to communicate with the provisioning server * user the VPP (Vovida Provisioning Protocol) protocol. * * Allows you open a connection, make any number of put and get operations, * and close the connection, abstracting away most of the details of the * transaction. */public class VPPTransaction implements Transaction{ public static int WRITE_TO_FILE = 1; public static int WRITE_TO_PSERVER = 2; public static int ERROR_MEANS_NO_SUCH_FILE = 0; public static int ERROR_MEANS_PERM_DENIED = 1; public static int ERROR_MEANS_AUTH_FAILED = 2; /** * True when this connection has been closed. * This is used to stop reconnect attempts. */ private boolean isClosed = false; /** * the size (in characters) of the buffer used to save up output from the * server */ private static final int blockSize = 4096; /** * Indicates whether there is currently a valid connection open to the * server. */ private boolean connected = false; /** * Indicates whether there is the connection has been authenticated by * server. */ private boolean authenticated = false; /** * The timeout for read operations from a socket input stream. This is used * to activate non-blocking io. Units are milliseconds. */ private static final int SOCKET_TIMEOUT = 12000; protected Socket socket; protected BufferedReader fromSocket; protected OutputStreamWriter toSocket; private Reconnect reconnect = null; private String host; private int port; public VPPTransaction(String server, int portNo) throws VPPException { host = server; port = portNo; // try and catch errors we know about, throw anything else try { System.out.println("creating socket to host " + server + ", port " + port); Socket tempSocket = new Socket(InetAddress.getByName(server), port); tempSocket.setSoTimeout(SOCKET_TIMEOUT); // because we are not connected yet, send manually. OutputStreamWriter tempToSocket = new OutputStreamWriter(tempSocket.getOutputStream());// BufferedReader tempFromSocket = new BufferedReader// (new InputStreamReader(tempSocket.getInputStream())); InputStreamReader tempFromSocket = new InputStreamReader(tempSocket.getInputStream()); tempToSocket.write("TLS . VPP/1.1\n"); tempToSocket.flush(); System.out.println("wrote TLS line to temp socket"); char nextCharacter; StringBuffer line = new StringBuffer(); while ((nextCharacter = (char) tempFromSocket.read()) != '\n') { line.append(nextCharacter); } StringBuffer contentLength = new StringBuffer(); while ((nextCharacter = (char) tempFromSocket.read()) != '\n') { contentLength.append(nextCharacter); } String response = new String(line); System.out.println("got response " + response); if ("200 OK".equals(response)) { SSLContext sslcontext; try { sslcontext = SSLContext.getInstance( "TLS"); } catch(java.security.NoSuchAlgorithmException ex) { // big error ex.printStackTrace(); String message = "The program could not open a socket to " + "the server \n" + server + " on port " + port + "\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } SSLSocketFactory sf; try { sslcontext.init( null, // No KeyManager required new TrustManager[] { new vocal.comm.TrustAllTrustManager() }, new java.security.SecureRandom()); } catch(java.security.KeyManagementException ex) { // big error ex.printStackTrace(); String message = "The program could not open a socket to " + "the server \n" + server + " on port " + port + "\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } sf = ( SSLSocketFactory) sslcontext.getSocketFactory();// // pserver can communicate on SSL socket// = (SSLSocketFactory)SSLSocketFactory.getDefault(); SSLSocket ssl = (SSLSocket)sf.createSocket(tempSocket, host, port, true); String list2[] = { "TLSv1" }; ssl.setEnabledProtocols(list2); String list[]; list = ssl.getEnabledProtocols(); System.out.println("protocols: " ); for (int i=0; i<list.length; i++) { System.out.println(" " + list[i]); } System.out.println("client: " + ssl.getUseClientMode()); // explicitly create the connection ssl.startHandshake(); socket = ssl; // disable blocking I/O by setting a timeout on the // socketInputStream.read operation socket.setSoTimeout(SOCKET_TIMEOUT); } else { //pserver cannot communicate on SSL socket JOptionPane.showMessageDialog(new JFrame(), "This connection is not encrypted", "Warning", JOptionPane.WARNING_MESSAGE); socket = tempSocket; } } catch (IOException ex) { ex.printStackTrace(); String message = "The program could not open a socket to " + "the server \n" + server + " on port " + port + "\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } try { fromSocket = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (IOException ex) { String message = "The server was contacted, but could " + "not be read from.\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } try { toSocket = new OutputStreamWriter(socket.getOutputStream()); } catch (IOException ex) { String message = "The server was contacted, but could " + "not be written to.\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } connected = true; // if we got here things must be ok... } /** * Read the status line (200... or 400...) of our VPP transaction * and verify that the status says OK. It is expected that the stream is * at the right position to read the status. */ protected String getStatusLine(int flag) throws VPPException { String statusLine = readLineFromSocket(); System.out.println("statusLine:"+statusLine); System.out.println("---TRACE--- VPPTransaction:reply - " + statusLine + Thread.currentThread()); // Our protocol demands that status line must start with the // return code. if (statusLine.startsWith("400")) { System.out.println("---TRACE--- VPPTransaction:" + "Got 400 -- Throwing exception"); if (flag == ERROR_MEANS_NO_SUCH_FILE) { throw new VPPNoSuchFileException("File Not Found"); } else if (flag == ERROR_MEANS_AUTH_FAILED) { /* this happens during normal operation */ return statusLine; } else { throw new VPPPermissionException("Permission Denied"); } } else if (!statusLine.startsWith("200")) { // throw the malformed message since we should get // one of 200 or 400 throw new VPPMalformedMsgException("The server did not " + "respond properly" + " to the command. " + "The result is: " + statusLine); } // else 200, so ok return statusLine; } /** * Read the content length line of our VPP transaction and verify * that it starts with the "Content-Length: " string. It assumes that the * underlying streams for this connection are at the right position to read * the content length. */ protected int getContentLength() throws VPPException { String contentLengthLine = readLineFromSocket(); // Verify that the line starts with "Content-Length: " if (!contentLengthLine.startsWith("Content-Length: ")) { throw new VPPMalformedMsgException("The Content-Length line from the server" + "was missing or malformed.\n" + "Its contents were:\n \"" + contentLengthLine + "\"."); } // we know the first 16 are the Content-Length, try to get the # String contentLengthAsString; contentLengthAsString = contentLengthLine.substring(16); int contentLength; try { contentLength = Integer.parseInt(contentLengthAsString); } catch (NumberFormatException e) { throw new VPPMalformedMsgException("The Content-Length line was corrupted\n" + "The contents were: \n \"" + contentLengthLine + "\"."); } return contentLength; } protected String getContents(int contentLength) throws IOException, VPPException { char[] buffer = new char[contentLength]; int totalCharsRead = 0; int charsRead = 0; StringBuffer response = new StringBuffer(); while (totalCharsRead < contentLength) { try { charsRead = fromSocket.read(buffer, 0, contentLength); } catch (IOException e) { System.out.println("Reconnecting"); reconnect(); } if (charsRead == -1) { throw new VPPMalformedMsgException("There was a problem in reading" + "the response:\n Content-Length was reported as " + contentLength + ", \n but the stream closed after only " + totalCharsRead + " characters."); } totalCharsRead += charsRead; response.append(buffer, 0, charsRead); } if (totalCharsRead < contentLength) { throw new VPPMalformedMsgException("There was a problem in reading the response: " + "\nContent-Length was reported as " + contentLength + ", \nbut the stream closed after only " + totalCharsRead + " characters."); } return response.toString(); } /** * Send a request string exactly as given. * @param requestType the type of request * @param requestString the string to be sent * @param entityToPut the rest of the content, if any * @return the server's response */ public synchronized String sendRequest(String requestType, String requestString, String entityToPut) throws VPPException { System.out.println("---TRACE--- VPPTransaction:request - " + requestString + Thread.currentThread()); System.out.println("|||||||||||||||||||||||||||||||"); System.out.println(requestString); if (!connected) { throw new VPPNoConnException("No connection to server"); } if (!authenticated) { throw new VPPAuthException("Connection to server not authenticated"); } // I get a warning about possibly throwing an undefined // variable below if I don't initialize this... VPPException exToThrow = new VPPException("No exception"); try { // Send the request toSocket.write(requestString); toSocket.flush();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -