[英]Socket Client-Server gets stuck after sending to server side
我需要使用Sockets为我的项目制作文件传输应用程序。 到目前为止,我已经编写了一个简单的客户端-服务器通信,但是每当我尝试将字符数据从客户端输出接收到服务器输入时,我的代码都会锁定。 这是代码:
服务器
public class ClientServer extends Thread {
Socket connection;
File file;
public ClientServer (Socket connection){
this.connection = connection;
this.start();
}
public void run(){
try {
System.out.println("Starting Client Thread...");
BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
System.out.println("IO created...");
System.out.println("input = " + input.readLine());
String s = input.readLine();
System.out.println(s);
file = new File(s);
if(file.isFile()){
System.out.println("File " + s + " exists");
FileInputStream fileOutput = new FileInputStream(file);
byte[] buffer = new byte[1024*1024];
int length = 0;
while((length = fileOutput.read(buffer)) != -1){
output.write(buffer, 0, buffer.length);
}
System.out.println("File " + s + " sent.");
fileOutput.close();
output.close();
input.close();
} else {
System.out.println(s + " is not a file");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
int serverPort = 9000;
ServerSocket server = new ServerSocket(serverPort);
Socket connectionSocket = server.accept();
ClientServer con = new ClientServer(connectionSocket);
}
}
客户
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String ip = "localhost";
int port = 9000;
Socket clientSocket = new Socket(ip, port);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter valid file name and press 'ENTER': ");
String message = userInput.readLine();
System.out.println("Sending message...");
out.write(message);
System.out.println("File name sent: " + message);
int length = in.readInt();
byte[] buffer = new byte[length];
for(int i=0; i< length; i++){
buffer[i] = in.readByte();
System.out.println("Reading byte... " + buffer[i]);
}
File file = new File("C:/Users/Dominik/Desktop/lol/new.php");
FileOutputStream fos = new FileOutputStream(file);
fos.write(buffer);
fos.close();
clientSocket.close();
System.out.println("Closing");
}
}
编辑
这是我的输出,因为没有答案可以解决我的问题(可能是我做错了什么):
客户
Enter valid file name and press 'ENTER': C:\\\\Users\\\\Dominik\\\\Desktop\\\\Login.php //my input Sending message... File name sent: C:\\\\Users\\\\Dominik\\\\Desktop\\\\Login.php
服务器
Starting Client Thread... IO created... //Server should sysout the message sent, but it doesn't do so, its just stuck here
您尝试在客户端中readInt
,但在服务器端仅发送文件内容。 我看起来您忘记了在发送文件之前发送文件的大小。
您正在阅读一行:
String s = input.readLine();
但您没有写一行:
out.write(message);
为此添加一个行终止符。
然后:
int length = in.readInt();
在这里,您正在读取一个永不发送的整数。 发送。
我认为您的通讯协议有误:
在服务器中,连接后,您需要客户端提供两个后续字符串
System.out.println("input = " + input.readLine());
String s = input.readLine();
但是客户端只发送一个(我认为您也应该按照EJP的建议添加一个行终止符)
然后,客户端需要一个整数,但服务器未发送该整数:
int length = in.readInt();
希望对您有帮助,祝您好运
编辑 (在12月23日进行编辑之后)
添加您的客户
out.flush();
在你之后
out.write(message + "\n");
然后修复协议。
我应用了您得到的所有建议,然后将其付诸实践
服务器:
public class ClientServer extends Thread {
Socket connection;
File file;
public ClientServer(Socket connection) {
this.connection = connection;
start();
}
@Override
public void run() {
try {
System.out.println("Starting Client Thread...");
BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
System.out.println("IO created...");
// System.out.println("input = " + input.readLine());
String s = input.readLine();
System.out.println(s);
file = new File(s);
if (file.isFile()) {
System.out.println("File " + s + " exists");
FileInputStream fileInput = new FileInputStream(file);
output.writeInt((int) file.length());
byte[] buffer = new byte[1024 * 1024];
int length = 0;
while ((length = fileInput.read(buffer)) != -1) {
output.write(buffer, 0, length);
}
System.out.println("File " + s + " sent.");
fileInput.close();
output.close();
input.close();
}
else {
System.out.println(s + " is not a file");
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
connection.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
int serverPort = 9000;
ServerSocket server = new ServerSocket(serverPort);
Socket connectionSocket = server.accept();
ClientServer con = new ClientServer(connectionSocket);
}
}
客户:
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String ip = "localhost";
int port = 9000;
Socket clientSocket = new Socket(ip, port);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter valid file name and press 'ENTER': ");
String message = userInput.readLine();
System.out.println("Sending message...");
out.write(message + "\n");
out.flush();
System.out.println("File name sent: " + message);
int length = in.readInt();
byte[] buffer = new byte[length];
for (int i = 0; i < length; i++) {
buffer[i] = in.readByte();
System.out.println("Reading byte... " + buffer[i]);
}
File file = new File("C:/test/fromServer.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write(buffer);
fos.close();
clientSocket.close();
System.out.println("Closing");
}
}
只是所有有用答案的一小部分:
在服务器端,写入文件的length
字节output.write(buffer, 0, length);
不要使用buffer.length,这通常会导致java.net.SocketException: Broken pipe
断开,因为客户端将在接收到length
字节后立即关闭套接字,但是服务器正在尝试写入整个1024 * 1024缓冲区。
同样在客户端上,您可以摆脱for循环并接收像这样的文件内容
byte[] buffer = new byte[length];
int bytesRead = in.read(buffer);
if (bytesRead != length) {
; // handle incomplete file transfer
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.