我创建了一个简单的实用程序,它实现了服务器和客户端。服务器等待连接,客户端连接,如果服务器上的文件夹中有任何文件 - 它们正在发送给客户端。 我使用 DataInput / OutputStreams - writeUTF / readUTF 在客户端和服务器之间发送消息, writeLong / readLong - 发送文件大小,写/读发送数据。 问题是,当我运行客户端和服务器时 - 发送一个或两个文件后工作卡住了。但是,如果我逐步跟踪IDE中的客户端和服务器,它的工作效果很好,如果我在一个字节中传输缓冲区大小的文件,它也可以工作 - 所以它工作得非常慢,但它不会卡住。 我在客户端使用Eclipse IDE,jdk 1.7,在服务器端使用1.8(也试过1.7),在两个VMWare播放器实例上使用Ubuntu linux和Windows 2003 Server。 我还试图添加Thread.sleep(10000)和flush()任何可能被刷新的东西,甚至添加 socket.setTcpNoDelay(true); 但没有结果。 看起来服务器发送下一个文件名并等待来自客户端的 echo(),但是客户端没有得到它并且卡在 readUTF()上。但是,如果我一步一步地在手动模式下执行它,它可以正常工作。 有任何想法吗?谢谢!
客户来源:
/**
* Method receives a file from server
* @param outWriter
* @param inBufferedReader
* @param inStream
*
*/
private void receiveFileFromServer(DataOutputStream out, DataInputStream in) {
try {
String fileName = in.readUTF(); ///<----- stucks here *************
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info("Receiving file "+fileName);
}
out.writeUTF(fileName);
out.flush();
Long fileSize = in.readLong();
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info("Filesize "+fileSize);
}
out.writeUTF(fileSize.toString());
out.flush();
File localFile = new File(fileName);
FileOutputStream fileOS = new FileOutputStream(localFile);
byte[] buffer = new byte [2048];
int bytesRead = 0;
try {
for (int i = 0; i<fileSize/buffer.length; i++) {
bytesRead = in.read(buffer, 0, buffer.length);
fileOS.write(buffer,0, bytesRead);
}
bytesRead = in.read(buffer, 0, (int)(fileSize%buffer.length));
fileOS.write(buffer,0, bytesRead);
System.out.println("----------------------- "+bytesRead);
} catch (IOException e) {
awlConnectionLogger.error("Error reading file "+fileName);
};
fileOS.close();
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info("File received.");
}
} catch (IOException e) {
awlConnectionLogger.error("Error reading Stream or socket closed");
}
}
/**
* Method sends a @param command to server, waits for answer, then if answer is not null and equals @param answer it logs @param messageOk else @param messageError
* returns true if everything is ok, else returns false
* @param outWriter
* @param inBufferedReader
* @throws IOException
*/
private boolean sendCommandReceiveAnswer(String command, String answer, String messageOk,String messageError,
DataOutputStream out, DataInputStream in) throws IOException {
out.writeUTF(command); //Hello handshake
out.flush();
String data = in.readUTF();
if ((data!=null)&&(data.equals(answer))) {
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info(messageOk);
}
return true;
} else {
awlConnectionLogger.error(messageError);
return false;
}
}
/**
* Try to establish connection with the awl-server according to detected RDP session
* @param serverIP - ip address of server
* @param user - username
*/
private void establishConnection(String serverIP, String user) {
if (awlConnectionLogger.isInfoEnabled()) {
awlConnectionLogger.info("Trying to establish awl-connection to "+serverIP+" as "+user);
}
Integer remoteAwlPort = Integer.parseInt(Config.awlPort);
try (Socket awlServerSocket = new Socket(serverIP,remoteAwlPort)) {//Creating autocloseable socket
this.awlServerSocket = awlServerSocket;
DataOutputStream out = new DataOutputStream(awlServerSocket.getOutputStream());
DataInputStream in = new DataInputStream(awlServerSocket.getInputStream());
if (!sendCommandReceiveAnswer("Hello-awl-client", "Hello-awl-server", "Server hello OK.",
"Unknown server type. Closing thread.", out, in)) {
return;
}; //Hello handshake - return if not successful
if (!sendCommandReceiveAnswer(user, "User-ok", "Username sent.", "Error sending username. Closing thread.", out, in)) {
return;
} //Sending username
String hostName = InetAddress.getLocalHost().getHostName(); //Getting client local hostname
if (!sendCommandReceiveAnswer(hostName, "Hostname-ok", "Local hostname "+hostName+" sent. Ready to receive files.",
"Error sending hostname. Closing thread.", out, in)) {
return;
} //Sending hostname
awlServerSocket.setTcpNoDelay(true);
while (isActive) {
receiveFileFromServer(out, in); //receiving files
out.writeUTF("Ready");
out.flush();
}
} catch (UnknownHostException e) {
awlConnectionLogger.error("Error in server IP adress");
} catch (SocketException e) {
awlConnectionLogger.error("Problem accessing or creating Socket.");
} catch (IOException e) {
awlConnectionLogger.error("General IO Error or Socket closed");
};
}
服务器来源:
void Echo (DataInputStream in) {
String echo = null;
try {
echo = in.readUTF();
System.out.println("Echo:"+echo);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void sendToClient (File file, DataOutputStream out, DataInputStream in) {
System.out.println("Sending file name "+file.getName());
try {
out.writeUTF(file.getName());
out.flush();
Echo (in); //<--------- stucks here *******************
out.writeLong(file.length());
out.flush();
Echo (in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Sending file");
byte [] buffer = new byte [2048];
FileInputStream fileIS = null;
try {
fileIS = new FileInputStream(file);
} catch (FileNotFoundException e) {
System.out.println("Error opening file "+file);
e.printStackTrace();
}
try {
Integer bytesRead;
int i = 0;
while((bytesRead=fileIS.read(buffer))>0) {
out.write(buffer, 0, bytesRead);
}
out.flush();
} catch (IOException e) {
System.out.println("Error reading file "+file);
e.printStackTrace();
};
System.out.println("File sent.");
try {
fileIS.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run () {
DataOutputStream out = null;
DataInputStream in = null;
String data = null;
String user = null;
String clientHostName = null;
try {
socket.setTcpNoDelay(true);
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("New incoming connection thread starded.");
try {
data = in.readUTF();
if (data.equals("Hello-awl-client")) {
System.out.println("Client hello OK.");
out.writeUTF("Hello-awl-server");
out.flush();
user = in.readUTF();
System.out.println("User: "+user);
out.writeUTF("User-ok");
out.flush();
clientHostName = in.readUTF();
System.out.println("Client hostname: "+clientHostName);
System.out.println("Server hostname: "+InetAddress.getLocalHost().getHostName());
out.writeUTF("Hostname-ok");
out.flush();
System.out.println("Ready to send files.");
while (isActive) {
File file = new File(ServerConfig.pdfFolder+"//"+user);
if (!file.isDirectory()) {
System.out.println("Error in path to user directory. Exiting thread");
return;
}
File [] files = file.listFiles();
for (File fileItem:files) {
while (!fileItem.renameTo(fileItem)) {
Thread.sleep(1000);
}; //waits while file is not busy to send it
if (socket.isOutputShutdown()) {
out = new DataOutputStream(socket.getOutputStream());
}
sendToClient (fileItem, out, in);
if (fileItem.delete()) {
System.out.println("File deleted.");
} else {
System.out.println("File not deleted.");
}
data = in.readUTF();
System.out.println(data);
}
}
} else {
System.out.println("Unknown connection type. Closing thread.");
return;
}
} catch (IOException | InterruptedException e) {
System.out.println("Connection error or can't sleep thread. Closing thread.");
return;
}
}