客户端套接字不会从服务器接收数据
Client socket will not receive data from server
我的问题是,在我的客户端中,dis.read()
正在返回 -1
,导致它从未真正收到文件。我唯一能想到的是,因为我在这个部分之前使用了一个PrintWriter
和一个BufferedReader
,所以dis.read()
认为已经收到了所有数据。
客户代码:
public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
Socket client = new Socket(serverAddress, port);
client.setSoTimeout(5000);
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
try {
out.println("101|" + fileName + "\n");
if (input.readLine().equals("201")) {
int br;
byte[] data = new byte[4096];
DataInputStream dis = new DataInputStream(client.getInputStream());
FileOutputStream fos = new FileOutputStream(fileOut);
while ((br = dis.read(data, 0, data.length)) != -1){
fos.write(data, 0, br);
}
fos.close();
dis.close();
}
} catch (SocketTimeoutException ste) {
ste.printStackTrace();
client.close();
}
}
服务器代码:
private void sendFile(String filename, Socket client) throws IOException {
int br;
byte[] data = new byte[4096];
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println("201\n");
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
FileInputStream fis = new FileInputStream(MeshFS.properties.getProperty("repository") + filename);
while ((br = fis.read(data, 0, data.length)) != -1) {
dos.write(data, 0, br);
dos.flush();
}
fis.close();
dos.close();
}
private String receiveRequest(Socket client) {
String requestPart;
String requestFull = "";
try {
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
while (((requestPart = input.readLine()) != null) && (requestFull.length() < 2048)) {
if (requestPart.equals("")) break;
requestFull = requestFull + requestPart;
}
return requestFull;
} catch (IOException ioe) {
return requestFull;
}
}
private void processRequest(String request, Socket out) {
if (request != null) {
try {
String[] requestParts = request.split("\|");
if (requestParts[0].equals("101")) { //101:Get file
sendFile(requestParts[1], out);
} else {
badRequest(out, request);
}
} catch (Exception e) {
badRequest(out, request);
e.printStackTrace();
}
}
}
public void run() {
while (!Thread.interrupted()) {
try {
server.setSoTimeout(1000);
Socket client = server.accept();
client.setSoTimeout(timeout);
processRequest(receiveRequest(client), client);
client.close();
} catch (SocketTimeoutException ste) {
} catch (IOException io) {
io.printStackTrace();
}
}
System.out.println("Socket closed");
}
是否有我遗漏或忘记包含的内容?我是不是在冲洗什么东西还是没有清理什么东西?
好的,我想我发现错误了。我做了一些实验,发现 InputStream
的行为很奇怪,如果多个对象试图从它们读取。在您的情况下,很可能是您客户的 receiveFile
方法中的 BufferedReader
和 DataInputStream
通过尝试读取相同的 inputStream
导致问题。我建议使用 DataInputStream
来读取第一行,这样您就不必创建 BufferedReader
。即使 DataInputStream.readLine()
方法已被弃用,它在您的情况下仍应表现良好。
我编辑了客户端 receiveFile
方法以使用 DataInputStream
读取第一行。希望有用!
public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
Socket client = new Socket(serverAddress, port);
client.setSoTimeout(5000);
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
DataInputStream dis = new DataInputStream(client.getInputStream());
try {
out.println("101|" + fileName + "\n");
if (dis.readLine().equals("201")) {
int br;
byte[] data = new byte[4096];
FileOutputStream fos = new FileOutputStream(fileOut);
while ((br = dis.read(data, 0, data.length)) != -1){
fos.write(data, 0, br);
}
fos.close();
dis.close();
}
} catch (SocketTimeoutException ste) {
ste.printStackTrace();
client.close();
}
}
我的问题是,在我的客户端中,dis.read()
正在返回 -1
,导致它从未真正收到文件。我唯一能想到的是,因为我在这个部分之前使用了一个PrintWriter
和一个BufferedReader
,所以dis.read()
认为已经收到了所有数据。
客户代码:
public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
Socket client = new Socket(serverAddress, port);
client.setSoTimeout(5000);
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
try {
out.println("101|" + fileName + "\n");
if (input.readLine().equals("201")) {
int br;
byte[] data = new byte[4096];
DataInputStream dis = new DataInputStream(client.getInputStream());
FileOutputStream fos = new FileOutputStream(fileOut);
while ((br = dis.read(data, 0, data.length)) != -1){
fos.write(data, 0, br);
}
fos.close();
dis.close();
}
} catch (SocketTimeoutException ste) {
ste.printStackTrace();
client.close();
}
}
服务器代码:
private void sendFile(String filename, Socket client) throws IOException {
int br;
byte[] data = new byte[4096];
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println("201\n");
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
FileInputStream fis = new FileInputStream(MeshFS.properties.getProperty("repository") + filename);
while ((br = fis.read(data, 0, data.length)) != -1) {
dos.write(data, 0, br);
dos.flush();
}
fis.close();
dos.close();
}
private String receiveRequest(Socket client) {
String requestPart;
String requestFull = "";
try {
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
while (((requestPart = input.readLine()) != null) && (requestFull.length() < 2048)) {
if (requestPart.equals("")) break;
requestFull = requestFull + requestPart;
}
return requestFull;
} catch (IOException ioe) {
return requestFull;
}
}
private void processRequest(String request, Socket out) {
if (request != null) {
try {
String[] requestParts = request.split("\|");
if (requestParts[0].equals("101")) { //101:Get file
sendFile(requestParts[1], out);
} else {
badRequest(out, request);
}
} catch (Exception e) {
badRequest(out, request);
e.printStackTrace();
}
}
}
public void run() {
while (!Thread.interrupted()) {
try {
server.setSoTimeout(1000);
Socket client = server.accept();
client.setSoTimeout(timeout);
processRequest(receiveRequest(client), client);
client.close();
} catch (SocketTimeoutException ste) {
} catch (IOException io) {
io.printStackTrace();
}
}
System.out.println("Socket closed");
}
是否有我遗漏或忘记包含的内容?我是不是在冲洗什么东西还是没有清理什么东西?
好的,我想我发现错误了。我做了一些实验,发现 InputStream
的行为很奇怪,如果多个对象试图从它们读取。在您的情况下,很可能是您客户的 receiveFile
方法中的 BufferedReader
和 DataInputStream
通过尝试读取相同的 inputStream
导致问题。我建议使用 DataInputStream
来读取第一行,这样您就不必创建 BufferedReader
。即使 DataInputStream.readLine()
方法已被弃用,它在您的情况下仍应表现良好。
我编辑了客户端 receiveFile
方法以使用 DataInputStream
读取第一行。希望有用!
public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
Socket client = new Socket(serverAddress, port);
client.setSoTimeout(5000);
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
DataInputStream dis = new DataInputStream(client.getInputStream());
try {
out.println("101|" + fileName + "\n");
if (dis.readLine().equals("201")) {
int br;
byte[] data = new byte[4096];
FileOutputStream fos = new FileOutputStream(fileOut);
while ((br = dis.read(data, 0, data.length)) != -1){
fos.write(data, 0, br);
}
fos.close();
dis.close();
}
} catch (SocketTimeoutException ste) {
ste.printStackTrace();
client.close();
}
}