向java服务器发送请求
我为服务器和客户机编写了一些代码,将文件从服务器传输到客户机,这就像一个符咒;然而,我有几个问题。我想在GUI下构建这段代码,我想列出文件夹中的所有文件,但是在看到提供的文件列表后,如何让客户机选择他想要的文件(如何向服务器发送字符串以选择文件) 服务器代码向java服务器发送请求,java,Java,我为服务器和客户机编写了一些代码,将文件从服务器传输到客户机,这就像一个符咒;然而,我有几个问题。我想在GUI下构建这段代码,我想列出文件夹中的所有文件,但是在看到提供的文件列表后,如何让客户机选择他想要的文件(如何向服务器发送字符串以选择文件) 服务器代码 import java.io.*; import java.net.*; class TCPServer { public static void listfile(){ File folder = new Fil
import java.io.*;
import java.net.*;
class TCPServer {
public static void listfile(){
File folder = new File("c:/");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
System.out.println("File " + listOfFiles[i].getName());
} else if (listOfFiles[i].isDirectory()) {
System.out.println("Directory " + listOfFiles[i].getName());
}
}
}
public static void main(String args[]) {
listfile();
while (true) {
ServerSocket welcomeSocket = null;
Socket connectionSocket = null;
BufferedOutputStream outToClient = null;
try {
welcomeSocket = new ServerSocket(3248);
connectionSocket = welcomeSocket.accept();
outToClient = new BufferedOutputStream(connectionSocket.getOutputStream());
} catch (IOException ex) {
// Do exception handling
}
if (outToClient != null) {
String FileName = "carexception.java";
File myFile = new File("C:\\"+FileName);
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = null;
try {
fis = new FileInputStream(myFile);
} catch (FileNotFoundException ex) {
// Do exception handling
}
BufferedInputStream bis = new BufferedInputStream(fis);
try {
bis.read(mybytearray, 0, mybytearray.length);
outToClient.write(mybytearray, 0, mybytearray.length);
outToClient.flush();
outToClient.close();
connectionSocket.close();
// File sent, exit the main method
return;
} catch (IOException ex) {
// Do exception handling
}
}
}
}
}
您是否尝试过创建数组,以便每个文件都有自己的索引。。。当客户机选择他想要的文件时,您将返回特定数组索引上的文件
~btw您可以序列化阵列并将其发送到客户端。如何询问文件?按姓名我认为服务器接受命令并响应。您可以使用命令到服务器的格式:CMD_NAME,arg1,arg2。。。参数可以是二进制的,具体取决于命令。通过CMD_名称,您的服务器将区分您想要的内容(接受文件或提供文件) 您有一个问题,即您只接受一种类型的请求。您需要一个命令机制来向服务器请求不同的请求。服务器需要解析这些请求,而不是立即给出硬编码的答案。这将使它具有灵活性
我相信还有很多其他类似的例子。Java套接字是可靠的,不会有问题。刚开始学习基础知识,如何在客户端和服务器之间传递不同的消息。但是,您的问题根本与套接字无关。假设您通过文件进行通信:从一个文件读取请求,然后将响应写入另一个文件。那么你写了哪些信息?这称为协议。你需要设计一个简单的 您可以使用
ObjectOutputStream
通过writeObject
发送字符串或任何其他类型的Object
,来完成您需要更改的内容
您可以假定一个特定的协议顺序,即客户端需要向服务器发送请求,以便服务器执行任何操作,因此在建立连接时,服务器始终处于侦听状态
你应该
ClientRequest request;
while (request.getType() != RequestType.Complete) {
// receive new request
// depending on type, send response
}
我们只是在这里添加了两个类,一个是封装客户端消息的ClientRequest
,另一个是定义客户端感兴趣的请求类型的enumRequestType
,例如文件列表或文件内容
public enum RequestType {
None, Complete, RequestFileList, RequestFileContent
}
public class ClientRequest {
private RequestType type;
public ClientRequest() {
type = RequestType.None;
}
public RequestType getType() {
return type;
}
}
现在我们需要以某种方式将其附加到套接字,因此我们添加了一个接收请求的方法,并将该请求分配给当前请求实例
ClientRequest request = new ClientRequest();
while (request.getType() != RequestType.Complete) {
// receive new request
receiveRequest(clientSocket.getInputStream(), request);
if (request.getType() != RequestType.Complete) {
// pick a response
}
}
private void receiveRequest(DataInputStream socketStream, ClientRequest request) {
// get a type of request
byte type = socketStream.readByte();
request.setType(RequestType.from(type));
// get parameters for request, depending on type
if (request.getType() == RequestType.RequestFileContent) {
// receive file id (file name for instance, or some other id that you prefer)
String argument = readString(socketStream);
request.setArgument(argument);
}
}
这将在RequestType中添加一个from
方法,将字节转换为请求;ClientRequest
中添加一个setType
方法,以及一个readString
方法。我们还在ClientRequest中添加了一个新字段以及相应的get和set方法
public enum RequestType {
// types as before
;
public static RequestType from(byte b) {
switch (b) {
case 1: return RequestType.Complete;
case 2: return RequestType.RequestFileList;
case 3: return RequestType.RequestFileContent;
default: return RequestType.None;
}
}
}
public class ClientRequest {
private String argument;
public void setType(RequestType value) {
type = value;
}
public String getArgument() {
return argument;
}
public void setArgument(String value) {
this.argument = value;
}
}
private String readString(DataInputStream socketStream) {
int length = socketStream.readInt();
byte[] stringBytes = new byte[length];
socketStream.read(stringBytes);
return new String(stringBytes, "UTF-8");
}
现在我们进入下一步,响应请求。只需添加一个开关盒并处理请求类型
{
// depending on type, send response
handleRequest(clientSocket.getOutputStream(), request);
}
private void handleRequest(DataOutputStream socketStream, ClientRequest request) {
switch (request.getType()) {
case RequestType.RequestFileList: {
String[] fileList = getFileList(getCurrentDirectory());
// send response type
socketStream.write(ResponseType.ResponseFileList.getByte());
// send number of files
socketStream.writeInt(fileList.length);
// send each string
for (String fileName : fileList) {
sendString(socketStream, fileName);
}
}
break;
case RequestType.RequestFileContent: {
// send response type ResponseType.ResponseFileContent
// send length of file so other party can determine number of bytes to receive
// send file contents in chunks of a fixed byte array length
// send last part of file contents, if length of file is not evenly divided by array chunk size
}
break;
}
}
sendString方法只是readString方法的“相反顺序”
private void sendString(DataOutputStream socketStream, String value) {
int length = value.length();
socketStream.writeInt(length);
byte[] stringBytes = value.getBytes("UTF-8");
socketStream.write(stringBytes);
}
ResponseType
是一个类似于RequestType
中的值的枚举,因此客户端可以处理服务器发送的响应类型
通过这些更改,您将能够请求文件列表并显示服务器发送的文件响应。当用户选择要接收的文件时,客户端可以向服务器发送新请求,服务器可以向客户端发送适当的文件内容
客户端应用程序必须定义一个类似的ClientRequest
类(可能名称为ServerResponse
),以及服务器指定用于读取和写入套接字流的相应方法。这可以通过在类中封装套接字来进一步抽象,在收到请求或响应时使用侦听器模式,GUI可以订阅这些请求或响应,……尽管这超出了我的示例
如果您觉得我需要澄清任何事情,请留下评论,我会尽力回答。可以,但我想显示文件列表,让客户通过键入他想要的文件来回复。我如何创建该文件feature@RaymondBouChaaya据我所知,您询问如何创建这样的GUI表单,您可以在其中选择一个文件名?当程序运行时,我希望客户端能够从可用文件列表中选择一个文件并解释编码方式?顺便说一句,如果您只是复制其他人的代码,您应该这样做。我在第一步就失去了您,你能试着把它添加到原始代码中吗?因为我不知道该怎么放,我会非常感激的。第一步呢?你是说循环码吗?您应该在建立连接后添加它。
private void sendString(DataOutputStream socketStream, String value) {
int length = value.length();
socketStream.writeInt(length);
byte[] stringBytes = value.getBytes("UTF-8");
socketStream.write(stringBytes);
}