我在java中制作简单的Client-Server FileTransfer应用程序。
以下是此应用程序的概念:
服务器向Client显示菜单,如下所示
问题是,当我选择其中一个选项时(例如选项#2a),我不能在之前完成时选择另一个选项。它说套接字很接近。
有我的代码:
客户端:
public class Client {
private Socket s = new Socket("localhost",3002);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
FileInputStream fis;
public Client(String host, int port) throws IOException {
//s = new Socket(host, port);
try {
System.out.println("Hello!");
boolean finished = false;
Scanner sc = new Scanner(System.in);
while(!finished){
System.out.println("\n\n1.Make copy of file on server");
System.out.println("2.Restore copy");
System.out.println("3.Exit\n");
char c = sc.nextLine().charAt(0);
switch(c){
case '1':
this.sendMessage(1);
makeCopy();
oos.close();
break;
case '2':
this.sendMessage(2);
saveFile(s);
break;
case '3':
this.sendMessage(3);
finished=true;
System.exit(0);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
Client client = new Client("localhost",3002);
}
public void sendMessage(int message_id) throws IOException{
oos.writeInt(message_id);
oos.flush();
}
private void makeCopy() throws IOException {
File file = new File("D:\\klient\\doKopii.bmp");
File dest = new File("D:\\serwer\\kopiaPliku.bmp");
boolean ifExists = dest.exists();
if(ifExists && !file.isDirectory()){
System.out.println("Copy is already on server.");
}
else{
fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
while (fis.read(buffer) > 0) {
oos.write(buffer);
}
}
//fis.close();
//oos.close();
}
private void saveFile(Socket clientSock) throws IOException {
//DataInputStream dis = new DataInputStream(clientSock.getInputStream());
FileOutputStream fos = new FileOutputStream("D:\\klient\\przywroconaKopia.bmp");
File zSerwera = new File("D:\\serwer\\kopiaPliku.bmp");
byte[] buffer = new byte[4096];
int filesize = (int)zSerwera.length();
int read = 0;
int totalRead = 0;
int remaining = filesize;
while((read = ois.read(buffer, 0, Math.min(buffer.length, remaining))) > 0) {
totalRead += read;
remaining -= read;
System.out.println("read " + totalRead + " bytes.");
fos.write(buffer, 0, read);
}
//fos.close();
//ois.close();
}
}
服务器端代码:
public class Server extends Thread{
private ServerSocket ss;
Socket clientSock;
ObjectInputStream ois;
ObjectOutputStream oos;
//DataOutputStream dos;
FileInputStream fis;
//DataInputStream dis;
FileOutputStream fos;
public Server(int port) {
try {
ss = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while (true) {
clientSock = ss.accept();
oos = new ObjectOutputStream(clientSock.getOutputStream());
ois = new ObjectInputStream(clientSock.getInputStream());
serviceClient(clientSock);
}
}catch(Exception e){
e.printStackTrace();
}
}
public void serviceClient(Socket s) throws Exception{
int message_id;
try{
message_id = ois.readInt();
switch(message_id){
case 1:
saveFile(s);
oos.flush();
break;
case 2:
sendFile(s);
oos.flush();
break;
}
}catch(Exception e){
e.printStackTrace();
}
}
public void sendFile(Socket s) throws IOException {
File file = new File("D:\\serwer\\kopiaPliku.bmp");
fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
while (fis.read(buffer) > 0) {
oos.write(buffer);
}
}
public void saveFile(Socket s) throws IOException{
//dis = new DataInputStream(s.getInputStream());
File copy = new File("D:\\serwer\\kopiaPliku.bmp");
if(copy.exists() && !copy.isDirectory()){
}
else{
fos = new FileOutputStream(copy);
File zSerwera = new File("D:\\klient\\doKopii.bmp");
byte[] buffer = new byte[4096];
int filesize = (int)zSerwera.length();
int read = 0;
int totalRead = 0;
int remaining = filesize;
while((read = ois.read(buffer, 0, Math.min(buffer.length, remaining))) > 0) {
totalRead += read;
remaining -= read;
System.out.println("read " + totalRead + " bytes.");
fos.write(buffer, 0, read);
}
}
}
public static void main(String[] args) {
Server server = new Server(3002);
server.start();
}
}
确切异常:
java.net.SocketException: Socket closed
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:116)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at java.io.ObjectOutputStream$BlockDataOutputStream.writeBlockHeader(ObjectOutputStream.java:1890)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1875)
at java.io.ObjectOutputStream$BlockDataOutputStream.flush(ObjectOutputStream.java:1822)
at java.io.ObjectOutputStream.flush(ObjectOutputStream.java:719)
at com.luki.classes.Client.sendMessage(Client.java:58)
at com.luki.classes.Client.<init>(Client.java:33)
at com.luki.classes.Client.main(Client.java:53)
我必须在哪里关闭所有这些流以防止套接字关闭?
答案 0 :(得分:0)
您在ObjectOutputStream
的第一个案例陈述结束时关闭Client
,原因无关紧要。删除该行,您将不会收到错误。