📄 chat.java
字号:
{
reportException("closeStreams()", e);
}
// inform user connection closed
log("Connection closed");
// set connected state
setConnected(false);
}
/** sets connection state */
protected void setConnected(boolean connected)
{
// set flag
connected = connected;
// set button states
btnConnect.setEnabled(!connected);
btnListen.setEnabled(!connected);
btnDisconnect.setEnabled(connected);
btnSendFile.setEnabled(connected);
btnReceiveFile.setEnabled(connected);
btnGenerateRSAkey.setEnabled(!connected);
// set remote machine state & other textfields
txtRemoteMachine.setEnabled(!connected);
txtPort.setEnabled(!connected);
txtTimeout.setEnabled(!connected);
// set message textfield state
txtMessage.setEnabled(connected);
if (connected)
txtMessage.requestFocus();
}
/** send file to the remote machine */
protected void sendFile()
{
// prompt user for file
FileDialog openFileDialog = new FileDialog(appletFrame, "Please select a file to send", FileDialog.LOAD);
openFileDialog.show();
// create a new sendFile object
outFile = new sendFile(this, openFileDialog.getDirectory(), openFileDialog.getFile());
outFile.setPriority(Thread.MIN_PRIORITY);
outFile.start();
// disable the send/receive buttons
btnSendFile.setEnabled(false);
btnReceiveFile.setEnabled(false);
}
/** receive file from the remote machine */
protected void receiveFile()
{
// create a new sendFile object
inFile = new receiveFile(this);
inFile.setPriority(Thread.MIN_PRIORITY);
inFile.start();
// disable the send/receive buttons
btnSendFile.setEnabled(false);
btnReceiveFile.setEnabled(false);
}
/** generates a new RSA key */
protected void generateRSAkey()
{
encMan.generateRSAkey(Integer.parseInt(txtRSAkeyLength.getText()));
}
/** exception handler */
protected void reportException(String description, Exception e)
{
// add the exception message to the conversation box
log(description + " - Exception class: " + e.getClass().getName() + " raised message: " + e.getMessage());
e.printStackTrace();
}
/** windowlistener events */
public void windowActivated(WindowEvent anEvent) {}
public void windowDeactivated(WindowEvent anEvent) {}
public void windowClosed(WindowEvent anEvent) {}
public void windowClosing (WindowEvent anEvent)
{
// this fires when the user selects "Close" from the applet's system menu
// need to specifically destroy the window ourselves
closeFrame();
}
public void windowDeiconified(WindowEvent anEvent) {}
public void windowIconified(WindowEvent anEvent) {}
public void windowOpened(WindowEvent anEvent) {}
/** keylistener events */
public void keyPressed(KeyEvent anEvent)
{
// send the message when the Enter key is pressed
if (anEvent.getKeyCode() == KeyEvent.VK_ENTER)
transmitMsg();
}
public void keyReleased(KeyEvent anEvent) {}
public void keyTyped(KeyEvent anEvent) {}
/** executed when user closes the frame */
public void closeFrame()
{
// if connected, disconnect from remote machine
if (connected)
disconnect();
// save properties to file
props.put("port", txtPort.getText());
// props.put("peerAddress", txtRemoteMachine.getText()); // forget this!
props.put("RSAKeyLength", txtRSAkeyLength.getText());
props.put("AESKeyLength", txtAESKeyLength.getText());
props.put("timeout", txtTimeout.getText());
try
{
props.store(new FileOutputStream(PROP_FILENAME), null);
}
catch (Exception e)
{
reportException("Error updating properties file", e);
try {Thread.sleep(10000); }catch (InterruptedException ie) {}
}
// destroy the frame
appletFrame.dispose();
// exit to o/s
System.exit(0);
}
/** class to listen for incoming messages from an input stream & display them on the screen */
class listener extends Thread
{
static final int STOP = 1;
static final int RUN = 2;
int state = RUN;
static final String DISCONNECT = "**D**";
chat parentProgram;
/** constructor */
public listener(chat _chat)
{
parentProgram = _chat;
}
/** main entry point */
public void run()
{
try
{
// declare message
String message = new String();
// loop until DISCONNECT command is received
while ((!message.equals(DISCONNECT)) & (okToContinue()))
{
// wait for the client to send some data
if (parentProgram.in.available() > 0)
{
// read a line of text
message = parentProgram.readString().trim();
// if message is not DISCONNECT, display message
if (!message.equals(DISCONNECT))
{
parentProgram.log("REMOTE: " + message);
// bring window to front if it's minimized
if (parentProgram.appletFrame.getState() == Frame.ICONIFIED)
{
parentProgram.appletFrame.setState(Frame.NORMAL);
}
parentProgram.appletFrame.toFront();
parentProgram.txtConversation.requestFocus(); // don't focus on the input window in case the user is currently typing...
}
else
{
parentProgram.log("** REMOTE MACHINE HAS DISCONNECTED **");
parentProgram.txtRemoteMachine.requestFocus();
}
}
else
{
Thread.sleep(500);
}
}
}
catch(Exception e)
{
parentProgram.reportException("run()", e);
}
finally
{
// close the input & output streams
parentProgram.closeStreams();
}
}
/** allows another object to stop this thread */
public synchronized void setState(int s)
{
state = s;
}
/** used by this object to check its status */
private synchronized boolean okToContinue()
{
if (state == RUN)
return true;
else
return false;
}
}
/** class to send file to remote machine */
class sendFile extends Thread
{
static final int STOP = 1;
static final int RUN = 2;
int state = RUN;
chat parentProgram;
String directory, fileName;
/** constructor */
public sendFile(chat _chat, String _directory, String _fileName)
{
// get handle to main program class
parentProgram = _chat;
// get file name
directory = _directory;
fileName = _fileName;
}
/** main entry point */
public void run()
{
try
{
try
{
// open another socket to the remote machine
Socket remoteSocket = new Socket(parentProgram.txtRemoteMachine.getText(), new Integer(parentProgram.txtPort.getText()).intValue()+1);
try
{
// create output stream
DataOutputStream fout = new DataOutputStream(remoteSocket.getOutputStream());
try
{
// encrypt the file name & convert to bytes
String filenameCipherText = encMan.encryptWithRijndael(fileName);
byte[] filenameCipherTextBuf = filenameCipherText.getBytes("UTF-8");
// send the length of the encrypted file name
fout.writeInt(filenameCipherTextBuf.length);
// send the encrypted file name
fout.write(filenameCipherTextBuf);
// inform user we have started to send file
parentProgram.log("Sending file...");
// open the data file
FileInputStream fin = new FileInputStream(directory + System.getProperty("file.separator") + fileName);
try
{
// read bytes from the input stream and write them to the output stream, encrypting as we go
byte[] bBlock = new byte[parentProgram.BUFFER_SIZE];
int bytesRead;
while ((bytesRead = fin.read(bBlock)) != -1)
{
byte[] tmp = new byte[bytesRead];
System.arraycopy(bBlock, 0, tmp, 0, bytesRead);
//System.out.println("sending plaintext=" + encMan.toHex(tmp));
byte[] bBlockEncrypted = encMan.encryptWithRijndael(tmp);
//System.out.println("sending ciphertext=" + encMan.toHex(bBlockEncrypted));
fout.writeInt(bBlockEncrypted.length);
fout.write(bBlockEncrypted, 0, bBlockEncrypted.length);
fout.flush();
}
fout.writeInt(0);
}
finally
{
fin.close();
}
// flush the stream
fout.flush();
}
finally
{
fout.close();
}
}
finally
{
remoteSocket.close();
}
// inform user we have finished sending file
parentProgram.log("File transmission complete...");
}
finally
{
// enable the send/receive buttons
parentProgram.btnSendFile.setEnabled(true);
parentProgram.btnReceiveFile.setEnabled(true);
}
}
catch(Exception e)
{
parentProgram.reportException("sendFile.run()", e);
}
}
/** allows another object to stop this thread */
public synchronized void setState(int s)
{
state = s;
}
/** used by this object check its status */
private synchronized boolean okToContinue()
{
if (state == RUN)
return true;
else
return false;
}
}
/** class to listen for incoming bytes & save them to a file */
class receiveFile extends Thread
{
static final int STOP = 1;
static final int RUN = 2;
int state = RUN;
chat parentProgram;
/** constructor */
public receiveFile(chat _chat)
{
// get handle to main program class
parentProgram = _chat;
}
/** main entry point */
public void run()
{
try
{
try
{
// create a server socket
ServerSocket listenSocket = new ServerSocket(new Integer(parentProgram.txtPort.getText()).intValue()+1, 1);
try
{
// set timeout
listenSocket.setSoTimeout(new Integer(parentProgram.txtTimeout.getText()).intValue() * 1000);
// inform user we are listening for a file to be sent
parentProgram.log("Waiting to receive file...");
// accept an incoming connection
Socket remoteSocket = listenSocket.accept();
try
{
// create the input stream
DataInputStream fin = new DataInputStream(remoteSocket.getInputStream());
try
{
// read the length of the encrypted file name in bytes
int encryptedFilenameLength = fin.readInt();
// read the encrypted file name bytes
byte[] encryptedFileNameBytes = new byte[encryptedFilenameLength];
int bytesOfFileNameRead = 0;
while (bytesOfFileNameRead < encryptedFileNameBytes.length)
{
bytesOfFileNameRead += fin.read(encryptedFileNameBytes, bytesOfFileNameRead, encryptedFilenameLength - bytesOfFileNameRead);
}
// decrypt the file name
String filenameCiphertext = new String(encryptedFileNameBytes, "UTF-8");
String filenamePlaintext = encMan.decryptWithRijndael(filenameCiphertext);
// create a dialog to prompt the user for the save location
FileDialog saveFileDialog = new FileDialog(parentProgram.appletFrame, "Select location to save file", FileDialog.SAVE);
// set the default file name read from the input stream
saveFileDialog.setFile(filenamePlaintext);
// display the dialog
saveFileDialog.show();
// get file name from dialog
String saveFileName = saveFileDialog.getDirectory() + System.getProperty("file.separator") + saveFileDialog.getFile();
// create the output file in the location specified by the user
FileOutputStream fout = new FileOutputStream(saveFileName);
try
{
// inform user the file has started to arrive
parentProgram.log("Receiving file...");
// read bytes from the input stream and write them to the output stream
int bytesInBlock;
while ((bytesInBlock = fin.readInt()) != 0)
{
byte[] bBlock = new byte[bytesInBlock];
int bytesOfBlockRead = 0;
while (bytesOfBlockRead < bytesInBlock)
{
bytesOfBlockRead += fin.read(bBlock, bytesOfBlockRead, bytesInBlock - bytesOfBlockRead);
}
//System.out.println("read ciphertext=" + encMan.toHex(bBlock));
byte[] plainText = encMan.decryptWithRijndael(bBlock);
//System.out.println("reading plaintext=" + encMan.toHex(plainText));
fout.write(plainText, 0, plainText.length);
}
}
finally
{
fout.close();
}
}
finally
{
fin.close();
}
}
finally
{
remoteSocket.close();
}
}
finally
{
listenSocket.close();
}
// inform user file received
parentProgram.log("** File received **");
}
finally
{
//enable the send/receive buttons
parentProgram.btnSendFile.setEnabled(true);
parentProgram.btnReceiveFile.setEnabled(true);
}
}
catch(Exception e)
{
parentProgram.reportException("receiveFile.run()", e);
}
}
/** allows another object to stop this thread */
public synchronized void setState(int s)
{
state = s;
}
/** used by this object to check its status */
private synchronized boolean okToContinue()
{
if (state == RUN)
return true;
else
return false;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -