我正在编写我的第一个使用客户端/服务器范例的Java Socket应用程序。
我有以下课程: SocketServer的 SocketClient
该应用程序的目标是让用户在客户端控制台/文件系统上输入.csv文件的文件路径:
1. Create a Server Program that uses a Socket.
a. The Server receives a CSV path/filename located on the Client from the Client.
b. The Server accesses the Client CSV file and converts it to an XML file.
c. The Server streams the XML file contents, not the XML path/file
name, back to the Client.
创建使用套接字的客户端程序。使用相同的端口 服务器
一个。提示用户输入CSV文件的路径/文件名。
湾将路径/文件名发送到服务器进行处理。
℃。从服务器套接字接收XML文件流。
d。将XML文件流保存到客户端上存储的文件中。
即将生成的XML文件存储在客户端的任何位置。
我已经编写了用于连接服务器和客户端上的套接字以及将.csv转换为.xml的代码,但是,我正在努力:
步骤1b。服务器访问客户端CSV文件并将其转换为 XML文件。
我是否可以直接从服务器访问位于客户端上的.csv文件 要么 我是否必须将文件路径从服务器传输回客户端,然后将文件传输到服务器进行转换,然后再传输新的XML文档?
根据说明,听起来应该有一种从服务器访问文件的方法。
这是我已编写的代码。
ClientController.java
public class ClientController extends ConsoleController {
// DEBUG
private static final boolean DEBUG = true;
private static final boolean DEBUG_STORE = false;
private static final boolean DEBUG_PROMPT = false;
private static final boolean DEBUG_VALUES = true;
// CONSTANTS
public static final String PROMPT_MESSAGE = "Enter the filepath to a '.csv' file to convert to a '.xml' file: ";
// MEMBERS
private String userFilepath;
private SocketClient mClient;
// CONSTRUCTORS
public ClientController() {
super();
mClient = null;
}
// LIFE-CYCLE METHODS
@Override
public void onCreate() {
// Setup the Connection to the Server
mClient = setupServerConnection();
// Get the path to the CSV file for conversion
requestPathToCSVFile();
// Attempt to Transfer the file
try {
sendPathToServer(userFilepath);
} catch (Exception e) {
System.out.println("Failed to transfer the file!");
System.out.println("Exception: ");
e.printStackTrace();
}
// Attempt to send some message 50 times
mClient.sendSomeMessages(3);
}
// CONVENIENCE METHODS
private SocketClient setupServerConnection() {
String hostname = "localhost";
int port = 54321;
byte[] data = "Hello Server".getBytes();
return new SocketClient(hostname, port, data);
}
private void requestPathToCSVFile() {
// Debug vars
boolean isEmpty = true;
boolean isDefaultMessage = true;
boolean isCSV = false;
while (true){
if (!isEmpty && !isDefaultMessage && isCSV) break;
// Prompt user
userFilepath = promptUser(PROMPT_MESSAGE);
System.out.println(userFilepath);
// Debugging
isEmpty = userFilepath.isEmpty();
isDefaultMessage = userFilepath.equals(DEFAULT_MESSAGE);
isCSV = isCSVPath(userFilepath);
// Output Debugging
if (DEBUG && DEBUG_VALUES) {
if (userFilepath != null) {
System.out.println("DEBUG userFilepath: " + userFilepath);
} else {
System.out.println("DEBUG userFilepath: isNull");
}
System.out.println("isEmpty: " + (isEmpty? "true":"false"));
System.out.println("DEBUG userFilepath:" + (isDefaultMessage? "true":"false"));
System.out.println("isCSVPath: " + (isCSVPath(userFilepath)? "true":"false"));
}
}
}
private void sendPathToServer(String path) {
// Send the filepath to the Server
mClient.sendMessage(path);
}
private boolean isCSVPath(String path) {
return Regex.hasExtension(path, "csv");
}
}
SocketServer.java
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
// An example of a very simple socket server.
public class SocketServer
{
// CONSTANTS
private static final boolean DEBUG = true;
private static final boolean DEBUG_NODES = true;
// FLAGS
private static final int FLAG_MESSAGE = 0;
private static final int FLAG_CONVERT_CSV_TO_XML = 1;
// CONSTANTS
private static final String TEMPORARY_FOLDER_PATH = "/tmp";
private static final String TEMP_CSV_FILENAME = "csvToConvertToXml.csv";
private static final String TEMP_XML_FILENAME = "xmlOfCsv.xml";
// MEMBERS
private int serverPort;
private ServerSocket mServerSocket = null;
private Socket mSocket;
private InputStream mSocketInput;
private OutputStream mSocketOutput;
private int mSocketFlag;
private String mPathToCsv;
public SocketServer(int serverPort)
{
this.serverPort = serverPort;
try
{
mServerSocket = new ServerSocket(serverPort);
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
}
public void waitForConnections()
{
mSocket = null;
mSocketInput = null;
mSocketOutput = null;
while (true)
{
// Open a Socket on the Server and Wait for a Connection
openSocket();
// TODO CODE THE FLAGGING
mSocketFlag = 1;
switch (mSocketFlag) {
case FLAG_MESSAGE:
handleConnection();
break;
case FLAG_CONVERT_CSV_TO_XML:
handleFileConversionConnection();
break;
}
// Now close the socket.
closeSocket();
}
}
// All this method does is wait for some bytes from the
// connection, read them, then write them back again, until the
// socket is closed from the other side.
public void handleFileConversionConnection()
{
while(true)
{
byte[] buffer = new byte[1024];
int bytes_read = 0;
try
{
// This call to read() will wait forever, until the
// program on the other side either sends some data,
// or closes the socket.
bytes_read = mSocketInput.read(buffer, 0, buffer.length);
// If the socket is closed, sockInput.read() will return -1.
if(bytes_read < 0)
{
System.err.println("Tried to read from socket, read() returned < 0, Closing socket.");
return;
}
// Set the mPathToCsv
mPathToCsv = new String(buffer, 0, bytes_read);
// Log the RECIEVED DATA
System.out.println("Server Received "+ bytes_read +" bytes, data=" + mPathToCsv);
System.out.println("mPathToCsv: " + mPathToCsv);
// Get the a the path supplied by the Client and save it in the /temp folder on the server
String pathToTempCsv = getFileFromClient(mPathToCsv,TEMPORARY_FOLDER_PATH, TEMP_CSV_FILENAME);
// Convert the Csv to XML
String pathToXmlForClient = convertCsvToXml(pathToTempCsv, TEMPORARY_FOLDER_PATH, TEMP_XML_FILENAME);
// Transfer the new XML Document to the Client
//transfer(pathToXmlForClient);
//
mSocketOutput.write(buffer, 0, bytes_read);
// This call to flush() is optional - we're saying go
// ahead and send the data now instead of buffering it.
mSocketOutput.flush();
}
catch (Exception e)
{
System.err.println("Exception reading from/writing to socket, e="+e);
e.printStackTrace(System.err);
return;
}
}
}
// All this method does is wait for some bytes from the
// connection, read them, then write them back again, until the
// socket is closed from the other side.
public void handleConnection()
{
while(true)
{
byte[] buffer = new byte[1024];
int bytes_read = 0;
try
{
// This call to read() will wait forever, until the
// program on the other side either sends some data,
// or closes the socket.
bytes_read = mSocketInput.read(buffer, 0, buffer.length);
// If the socket is closed, sockInput.read() will return -1.
if(bytes_read < 0)
{
System.err.println("Tried to read from socket, read() returned < 0, Closing socket.");
return;
}
System.out.println("Server Received "+ bytes_read +" bytes, data=" + (new String(buffer, 0, bytes_read)));
mSocketOutput.write(buffer, 0, bytes_read);
// This call to flush() is optional - we're saying go
// ahead and send the data now instead of buffering it.
mSocketOutput.flush();
}
catch (Exception e)
{
System.err.println("Exception reading from/writing to socket, e="+e);
e.printStackTrace(System.err);
return;
}
}
}
public void openSocket() {
try
{
// This method call, accept(), blocks and waits
// (forever if necessary) until some other program
// opens a socket connection to our server. When some
// other program opens a connection to our server,
// accept() creates a new socket to represent that
// connection and returns.
mSocket = mServerSocket.accept();
System.err.println("Have accepted new socket.");
// From this point on, no new socket connections can
// be made to our server until accept() is called again.
mSocketInput = mSocket.getInputStream();
mSocketOutput = mSocket.getOutputStream();
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
}
public void closeSocket() {
try
{
System.err.println("Closing socket.");
mSocket.close();
}
catch (Exception e)
{
System.err.println("Exception while closing socket.");
e.printStackTrace(System.err);
}
System.err.println("Finished with socket, waiting for next connection.");
}
// CONVENIENCE METHODS
public void transfer(String sfile) throws IOException {
if (DEBUG && DEBUG_NODES) System.out.println("Enter transfer(String sfile)");
// Create a new File object
File myFile = new File(sfile);
while (true) {
byte[] mybytearray = new byte[(int) myFile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
bis.read(mybytearray, 0, mybytearray.length);
// Get the OutputStream for the Socket
mSocketOutput.write(mybytearray, 0, mybytearray.length);
mSocketOutput.flush();
// Close the socket
bis.close();
}
}
public String getFileFromClient(String pathToFile, String destinationDirectory, String newFilename) {
if (DEBUG && DEBUG_NODES) System.out.println("Enter getFileFromClient(String pathToFile, String destinationDirectory, String newFilename)");
String pathToNewFile = destinationDirectory + "/" + newFilename;
// TODO GET THE FILE FROM THE CLIENT
if (DEBUG && DEBUG_NODES) System.out.println("Exit getFileFromClient(String pathToFile, String destinationDirectory, String newFilename)");
return pathToNewFile;
}
public String convertCsvToXml(String pathToCsv, String pathToDestinationDirectory, String newFilename) {
if (DEBUG && DEBUG_NODES) System.out.println("Enter convertCsvToXml(String pathToCsv, String pathToDestinationDirectory, String newFilename)");
String pathToNewFile = pathToDestinationDirectory + "/" + newFilename;
// TODO CREATE THE NEW FILE AND CONVERT THE CSV TO XML
XMLWriter xmlFile = new XMLWriter(pathToCsv, pathToNewFile);
xmlFile.csvToXml();
if (DEBUG && DEBUG_NODES) System.out.println("Exit convertCsvToXml(String pathToCsv, String pathToDestinationDirectory, String newFilename)");
return pathToNewFile;
}
public static void main(String argv[])
{
int port = 54321;
SocketServer server = new SocketServer(port);
server.waitForConnections();
}
}
SocketClient.java
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class SocketClient
{
// CONSTANTS
public static final int TRANSFER_SIZE_1KB = 1024;
// MEMBERS
private String mServerHostname = null;
private int mServerPort = 0;
private byte[] data = null;
private Socket mSocket = null;
private InputStream mSocketInput = null;
private OutputStream mSocketOutput = null;
public SocketClient(String ServerHostname, int ServerPort)
{
this(ServerHostname, ServerPort, null);
}
public SocketClient(String mServerHostname, int mServerPort, byte[] data)
{
this.mServerHostname = mServerHostname;
this.mServerPort = mServerPort;
this.data = data;
}
public void transfer( String outfile ) throws Exception {
// Open the Socket
openSocket();
// Create a new byte array size of 1KB
byte[] bytearray = new byte[TRANSFER_SIZE_1KB];
// Create a bufferedOutputStream from the outfile path
FileOutputStream fos = new FileOutputStream(outfile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
// TESTING
fos.toString();
// Initialize values to 0
int bytesRead = 0;
int count = 0;
System.out.println("GOT HERE");
// Transfer the 'outfile' 1KB (1024 bytes) increments, each pass is 1KB chunk of files
while ((bytesRead = mSocketInput.read(bytearray, 0, bytearray.length)) != -1)
{
System.out.println("GOT HERE");
// Send the data to the Server
bos.write(bytearray, 0, bytesRead);
// If less than 1KB, finish the transfer using flush()
bos.flush();
System.out.println(++count);
}
// Log to console
System.out.println("Finished transferring " + outfile);
// Close the bufferedOutputStream
bos.close();
// Close the socket
closeSocket();
}
public void sendSomeMessages(int iterations)
{
// Open the Socket
openSocket();
byte[] buf = new byte[data.length];
int bytes_read = 0;
for(int x=1; x<=iterations; x++)
{
try
{
mSocketOutput.write(data, 0, data.length);
bytes_read = mSocketInput.read(buf, 0, buf.length);
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
if( bytes_read != data.length )
{
System.out.println("run: Sent "+ data.length +" bytes, server should have sent them back, read "+bytes_read+" bytes, not the same number of bytes.");
}
else
{
System.out.println("Client Sent "+bytes_read+" bytes to server and received them back again, msg = "+(new String(data)));
}
// Sleep for a bit so the action doesn't happen to fast -
// this is purely for reasons of demonstration, and not required technically.
try { Thread.sleep(50);}
catch (Exception e) {};
}
System.err.println("Done reading/writing to/from socket, closing socket.");
// Close the Socket
closeSocket();
}
public void sendMessage(String str) {
// Open the Socket
openSocket();
// Convert the String to a Byte Array
byte[] data = str.getBytes();
// Create a buffer object the size of the data byte array
byte[] buf = new byte[data.length];
int bytes_read = 0;
// Attempt to send the data over the network
try
{
mSocketOutput.write(data, 0, data.length);
bytes_read = mSocketInput.read(buf, 0, buf.length);
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
if( bytes_read != data.length )
{
System.out.println("run: Sent "+ data.length +" bytes, server should have sent them back, read "+bytes_read+" bytes, not the same number of bytes.");
}
else
{
System.out.println("Client Sent "+bytes_read+" bytes to server and received them back again, msg = "+(new String(data)));
}
// Sleep for a bit so the action doesn't happen to fast -
// this is purely for reasons of demonstration, and not required technically.
try { Thread.sleep(50);}
catch (Exception e) {};
System.err.println("Done reading/writing to/from socket, closing socket.");
// Close the Socket
closeSocket();
}
public void openSocket() {
// Open the Socket
System.err.println("Opening connection to "+mServerHostname+" port "+mServerPort);
try
{
mSocket = new Socket(mServerHostname, mServerPort);
mSocketInput = mSocket.getInputStream();
mSocketOutput = mSocket.getOutputStream();
}
catch (IOException e)
{
e.printStackTrace(System.err);
return;
}
System.err.println("About to start reading/writing to/from socket.");
}
public void closeSocket() {
// Close the Socket
try
{
mSocket.close();
}
catch (IOException e)
{
System.err.println("Exception closing socket.");
e.printStackTrace(System.err);
}
System.err.println("Exiting.");
}
// GETTERS & SETTERS
public String getServerHostname() {
return mServerHostname;
}
public void setServerHostname(String serverHostname) {
this.mServerHostname = mServerHostname;
}
public int getServerPort() {
return mServerPort;
}
public void setServerPort(int serverPort) {
this.mServerPort = mServerPort;
}
public Socket getSocket() {
return mSocket;
}
public void setSocket(Socket socket) {
this.mSocket = mSocket;
}
public InputStream getSocketInput() {
return mSocketInput;
}
public void setSocketInput(InputStream socketInput) {
this.mSocketInput = mSocketInput;
}
public OutputStream getSocketOutput() {
return mSocketOutput;
}
public void setSocketOutput(OutputStream socketOutput) {
this.mSocketOutput = mSocketOutput;
}
}
支持课程
ConsoleController.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
@SuppressWarnings("unused")
public abstract class ConsoleController {
// DEBUG
private static final boolean DEBUG = false;
private static final boolean DEBUG_STORE = false;
private static final boolean DEBUG_PROMPT = false;
private static final boolean DEBUG_VALUES = false;
// CONSTANTS
protected static final String DEFAULT_MESSAGE = "No input recieved";
// MEMBERS
private String mRecentInput;
// CONSTRUCTORS
public ConsoleController() {
mRecentInput = DEFAULT_MESSAGE;
}
// LIFE-CYCLE METHODS
abstract public void onCreate();
public String promptUser(String userPrompt) {
System.out.println(userPrompt);
try{
// Create BufferedReader to read from the Console
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
// Read the line from the console
mRecentInput = bufferRead.readLine();
if (mRecentInput.equalsIgnoreCase("Exit")) exit();
}
catch(IOException e)
{
e.printStackTrace();
}
return mRecentInput;
}
public String getInput() {
return mRecentInput;
}
public void exit() {
//System.out.println("Quiting");
System.exit(0);
}
}
Regex.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressWarnings("unused")
public class Regex {
public static final boolean DEBUG = false;
public static final boolean DEBUG_HAS_EXT = true;
public static boolean hasExtension(String path, String extension) {
// Match Numberic and Hexadecimal Values
Pattern extTest = Pattern.compile("\\.(" + extension.trim() + ")$");
Matcher values = extTest.matcher(path);
if (DEBUG && DEBUG_HAS_EXT) {
System.out.println("Regex - Extension Matches");
System.out.println("Search String: " + path);
System.out.println("Pattern: " + extTest.pattern());
System.out.print("Match: ");
}
// Returns true if there is anotherMatch remaining, returns false if no matches remain
boolean anotherMatch = values.find();
if (anotherMatch == true) {
while(anotherMatch) {
// If we get here, there is a match
// Log
if (DEBUG && DEBUG_HAS_EXT) System.out.println(values.group());
// Check to see if there is anotherMatch
anotherMatch = values.find();
}
return true;
} else {
if (DEBUG && DEBUG_HAS_EXT) System.out.println("There was no match");
return false;
}
}
}
XMLWriter.java
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
public class XMLWriter
{
// Members
private Document mDocumentForOutput;
private String mInFilePath;
private String mOutFilePath;
// CONSTRUCTORS
public XMLWriter(String filePathForConversion, String filePathForOutput) {
mInFilePath = filePathForConversion;
mOutFilePath = filePathForOutput;
try {
mDocumentForOutput = createDocument();
} catch (Exception e) {
System.out.println("Exception: ");
e.printStackTrace();
}
}
public Document createDocument() throws IOException, ParserConfigurationException
{
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
return doc;
}
public void processDocument(String delimeter) throws Exception
{
// Get a File object from the InPath
File inFile = new File(mInFilePath);
// Create a BufferedReader from the file
BufferedReader reader = new BufferedReader(new FileReader(inFile));
// Read a line from the file
String sline = reader.readLine();
//
String[] sheaders = sline.split(delimeter);
sline = reader.readLine();
String[] snodes = sline.split(delimeter);
Element aroot;
Element achild;
aroot = mDocumentForOutput.createElement(sheaders[0].trim());
mDocumentForOutput.appendChild(aroot);
while ((sline=reader.readLine()) != null)
{
achild = mDocumentForOutput.createElement(sheaders[1].trim());
String[] sdata = sline.split(delimeter);
for (int x=0; x<snodes.length; ++x)
{
Element c = mDocumentForOutput.createElement(snodes[x].trim());
c.appendChild(mDocumentForOutput.createTextNode(sdata[x].trim()));
achild.appendChild(c);
}
aroot.appendChild(achild);
}
}
public void createXML() throws Exception
{
//TransformerFactory instance is used to create Transformer objects.
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// create string from xml tree
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(mDocumentForOutput);
transformer.transform(source, result);
String xmlString = sw.toString();
File file = new File(mOutFilePath);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
bw.write(xmlString);
bw.flush();
bw.close();
}
public void createXmlDocument(String delimeter) throws Exception
{
processDocument(delimeter);
createXML();
}
public void csvToXml() {
try {
createXmlDocument(",");
} catch (Exception e) {
System.out.print("Exception: ");
e.printStackTrace();
}
}
public static void testWriter(String csvFile)
{
try
{
try {
XMLWriter xmlWriter = new XMLWriter(csvFile, "Output.xml");
xmlWriter.csvToXml();
} catch (Exception e) {
System.out.println("'" + csvFile + "' does not exist in the given directory! Please check that you have properly entered your filepath");
}
System.out.println("<b>Xml File Created Successfully</b>");
}
catch(Exception e)
{
System.out.println(e);
}
}
}