我做了一些不同的教程,但没有任何作用,有人能看到我做错了吗?
private volatile boolean keepRunning = true;
public FileSharedServer() {
}
@Override
public void run() {
try {
System.out.println("Binding to Port " + PORT + "...");
// Bind to PORT used by clients to request a socket connection to
// this server.
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("\tBound.");
System.out.println("Waiting for Client...");
socket = serverSocket.accept();
System.out.println("\tClient Connected.\n\n");
if (socket.isConnected()) {
System.out.println("Writing to client serverId " + serverId
+ ".");
// Write the serverId plus the END character to the client thru
// the socket
// outStream
socket.getOutputStream().write(serverId.getBytes());
socket.getOutputStream().write(END);
}
while (keepRunning) {
System.out.println("Ready");
// Receive a command form the client
int command = socket.getInputStream().read();
// disconnect if class closes connection
if (command == -1) {
break;
}
System.out.println("Received command '" + (char) command + "'");
// decide what to do.
switch (command) {
case LIST_FILES:
sendFileList();
break;
case SEND_FILE:
sendFile();
break;
default:
break;
}
}
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
// Do not close the socket here because the readFromClient() method
// still needs to
// be called.
if (socket != null && !socket.isClosed()) {
try {
System.out.println("Closing socket.");
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* This method sends the names of all of the files in the share directory.
*
* @throws IOException
*/
private void sendFileList() throws IOException {
File serverFilesDir = new File("serverFiles/");
if (!serverFilesDir.exists() || serverFilesDir.isFile()) {
System.out.println("'serverfiles' is not an existing directory");
throw new IOException("'serverfiles' directory does not exist.");
}
File[] files = serverFilesDir.listFiles();
for (File file : files) {
socket.getOutputStream().write(file.getName().getBytes());
// Even the last one must end with END and then finally with
// END_OF_LIST.
socket.getOutputStream().write(END);
}
socket.getOutputStream().write(END_OF_LIST);
}
/**
* this methods sends a particular file to the client.
*
* @throws IOException
*/
private void sendFile() throws IOException {
StringBuilder filename = new StringBuilder();
int character = -1;
while ((character = socket.getInputStream().read()) > -1
&& character != END && (char) character != END_OF_LIST) {
filename.append((char) character);
}
System.out.println(filename);
File file = new File(System.getProperty("user.dir")
+ System.getProperty("file.separator") + "serverfiles",
filename.toString());
String totalLength = String.valueOf(file.length());
socket.getOutputStream().write(totalLength.getBytes());
socket.getOutputStream().write(END);
FileInputStream fileInputStream = new FileInputStream(file);
int nbrBytesRead = 0;
byte[] buffer = new byte[1024 * 2];
try {
while ((nbrBytesRead = fileInputStream.read(buffer)) > -1) {
socket.getOutputStream().write(buffer, 0, nbrBytesRead);
}
} finally {
fileInputStream.close();
}
}
public static void main(String[] args) throws InterruptedException {
// Create the server which waits for a client to request a connection.
FileSharedServer server = new FileSharedServer();
System.out.println("new thread");
Thread thread = new Thread(server);
thread.start();
}
}
我需要另一个课程还是主要的几行?在最底层。
这是一个无线网络,我需要的是两个客户端,或者更多:)
答案 0 :(得分:3)
这里的问题是您在服务器上只运行一个线程。此线程接受连接,将服务器ID写入连接,然后从连接读取。然后线程继续从连接读取,直到收到-1,此时线程退出。线程决不会尝试接受第二个连接; ServerSocket.accept()只被调用一次。因此,您只能处理一个客户端。
您需要的是将您的班级分成两个单独的班级。在第一个类中,run()方法进入循环,调用ServerSocket.accept(),每次该方法返回一个套接字时,创建第二个类的实例,将其交给套接字,然后启动它,之后它循环回到ServerSocket.accept()调用。
第二个类几乎与您已编写的类相同,只是它不包含ServerSocket.accept()调用。相反,socket
是一个成员变量,由第一个类在启动之前初始化。它可以完成套接字的所有处理,发送服务器ID,接收和处理命令等,就像您现有的代码一样。