Java 套接字卡在 readUTF() 上
Java socket is stuck on readUTF()
我正在尝试通过 Java 中的套接字传输文件,我目前的服务器方法是:
- 创建新话题
- 线程使用dos.writeUTF()
发送文件名
- 线程使用dos.writeLong()
发送文件大小
- 线程使用dos.write()
发送文件
其中每个线程代表一个客户端,dos 是 DataOutputStream 的一个实例。
现在,我在客户端上做同样的事情,但阅读而不是写作:
- 使用dis.readUTF()
读取文件名
- 使用dis.readLong()
读取文件大小
- 使用dis.read()
读取文件
其中 dis 是 DataInputStream 的实例。
问题是:发送一个文件时,一切正常,但是当我尝试一个接一个地发送 3 个文件时,看起来服务器正在按预期将所有内容正确写入流,但客户端(在第一个文件之后,意味着这从第二个文件开始发生)卡在 dis.readUTF() 上,无法继续。
我已经尝试修复此问题好几天了,但无法正常工作。
这是源代码:
服务器:
Main.java
public class Main {
public static void main(String[] args) {
boolean boolDebug = true;//TODO REMOVE THIS!!
ServerSocket serverSock = null;
List<Socket> clientSocks;
List<ClientThread> clientThreads;
try {
serverSock = new ServerSocket(9090);
} catch(Exception e){
e.printStackTrace();
}
clientSocks = new ArrayList<>();
clientThreads = new ArrayList<>();
ServerSocket finalServerSock = serverSock;
System.out.println();
System.out.println("Listening for incoming connections\n");
new Thread(){
@Override
public void run() {
super.run();
while (true) {
try {
Socket newSock = finalServerSock.accept();
clientSocks.add(newSock); //FIXME Remove sockets when closed
Thread thread = new ClientThread(newSock, usr, psw);
thread.start();
clientThreads.add((ClientThread)thread);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
}
}
ClientThread.java
public class ClientThread extends Thread {
private Socket socket;
private DataInputStream inStream;
private DataOutputStream outStream;
private String dbUser;
private String dbPassword;
public ClientThread(Socket socket, String DbUser, String DbPass) {
this.socket = socket;
this.dbUser = DbUser;
this.dbPassword = DbPass;
}
@Override
public void run() {
try {
inStream = new DataInputStream(socket.getInputStream());
outStream = new DataOutputStream(socket.getOutputStream());
sendFile("a.txt");
sendFile("b.txt");
sendFile("c.txt");
} catch (Exception e) {
e.printStackTrace();
}
}
void sendFile(String file){
try {
File f = new File(file);
outStream.writeUTF(file);
outStream.writeLong(f.length());
FileInputStream fis = new FileInputStream(f);
byte[] buffer = new byte[4096];
while (fis.read(buffer) > 0) {
outStream.write(buffer);
}
fis.close();
}catch(Exception e){
e.printStackTrace();
}
}
int getSize(byte[] buffer,long remaining){
try {
return Math.toIntExact(Math.min(((long) buffer.length), remaining));
}catch(ArithmeticException e){
return 4096;
}
}
}
客户:
Main.java
class Main {
static int getSize(byte[] buffer, long remaining) {
try {
return Math.toIntExact(Math.min(((long) buffer.length), remaining));
} catch (ArithmeticException e) {
return 4096;
}
}
static void saveFile(Socket clientSock,DataInputStream dis) throws IOException {
String fileName = dis.readUTF();
File f = new File(fileName);
FileOutputStream fos = new FileOutputStream(f);
byte[] buffer = new byte[4096];
long filesize = dis.readLong();
int read = 0;
int totalRead = 0;
long remaining = filesize;
while ((read = dis.read(buffer, 0, getSize(buffer, remaining))) > 0) {
totalRead += read;
remaining -= read;
System.out.println("read " + totalRead + " bytes.");
fos.write(buffer, 0, read);
}
fos.close();
}
public static void main(String[] args) throws Exception {
Socket sock = new Socket("192.168.2.17", 9090);
DataInputStream dis = new DataInputStream(sock.getInputStream());
saveFile(sock,dis);
saveFile(sock,dis);
saveFile(sock,dis);
}
}
非常感谢,期待解决此问题:(
通过更改
修复
while (fis.read(buffer) > 0) {
outStream.write(buffer);
}
至
int count;
while ((count = fis.read(buffer)) > 0) {
outStream.write(buffer, 0, count);
}
服务器端ClientThread.java内部
我正在尝试通过 Java 中的套接字传输文件,我目前的服务器方法是:
- 创建新话题
- 线程使用dos.writeUTF() 发送文件名
- 线程使用dos.writeLong() 发送文件大小
- 线程使用dos.write() 发送文件
其中每个线程代表一个客户端,dos 是 DataOutputStream 的一个实例。
现在,我在客户端上做同样的事情,但阅读而不是写作:
- 使用dis.readUTF() 读取文件名
- 使用dis.readLong() 读取文件大小
- 使用dis.read() 读取文件
其中 dis 是 DataInputStream 的实例。
问题是:发送一个文件时,一切正常,但是当我尝试一个接一个地发送 3 个文件时,看起来服务器正在按预期将所有内容正确写入流,但客户端(在第一个文件之后,意味着这从第二个文件开始发生)卡在 dis.readUTF() 上,无法继续。
我已经尝试修复此问题好几天了,但无法正常工作。
这是源代码:
服务器:
Main.java
public class Main {
public static void main(String[] args) {
boolean boolDebug = true;//TODO REMOVE THIS!!
ServerSocket serverSock = null;
List<Socket> clientSocks;
List<ClientThread> clientThreads;
try {
serverSock = new ServerSocket(9090);
} catch(Exception e){
e.printStackTrace();
}
clientSocks = new ArrayList<>();
clientThreads = new ArrayList<>();
ServerSocket finalServerSock = serverSock;
System.out.println();
System.out.println("Listening for incoming connections\n");
new Thread(){
@Override
public void run() {
super.run();
while (true) {
try {
Socket newSock = finalServerSock.accept();
clientSocks.add(newSock); //FIXME Remove sockets when closed
Thread thread = new ClientThread(newSock, usr, psw);
thread.start();
clientThreads.add((ClientThread)thread);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
}
}
ClientThread.java
public class ClientThread extends Thread {
private Socket socket;
private DataInputStream inStream;
private DataOutputStream outStream;
private String dbUser;
private String dbPassword;
public ClientThread(Socket socket, String DbUser, String DbPass) {
this.socket = socket;
this.dbUser = DbUser;
this.dbPassword = DbPass;
}
@Override
public void run() {
try {
inStream = new DataInputStream(socket.getInputStream());
outStream = new DataOutputStream(socket.getOutputStream());
sendFile("a.txt");
sendFile("b.txt");
sendFile("c.txt");
} catch (Exception e) {
e.printStackTrace();
}
}
void sendFile(String file){
try {
File f = new File(file);
outStream.writeUTF(file);
outStream.writeLong(f.length());
FileInputStream fis = new FileInputStream(f);
byte[] buffer = new byte[4096];
while (fis.read(buffer) > 0) {
outStream.write(buffer);
}
fis.close();
}catch(Exception e){
e.printStackTrace();
}
}
int getSize(byte[] buffer,long remaining){
try {
return Math.toIntExact(Math.min(((long) buffer.length), remaining));
}catch(ArithmeticException e){
return 4096;
}
}
}
客户: Main.java
class Main {
static int getSize(byte[] buffer, long remaining) {
try {
return Math.toIntExact(Math.min(((long) buffer.length), remaining));
} catch (ArithmeticException e) {
return 4096;
}
}
static void saveFile(Socket clientSock,DataInputStream dis) throws IOException {
String fileName = dis.readUTF();
File f = new File(fileName);
FileOutputStream fos = new FileOutputStream(f);
byte[] buffer = new byte[4096];
long filesize = dis.readLong();
int read = 0;
int totalRead = 0;
long remaining = filesize;
while ((read = dis.read(buffer, 0, getSize(buffer, remaining))) > 0) {
totalRead += read;
remaining -= read;
System.out.println("read " + totalRead + " bytes.");
fos.write(buffer, 0, read);
}
fos.close();
}
public static void main(String[] args) throws Exception {
Socket sock = new Socket("192.168.2.17", 9090);
DataInputStream dis = new DataInputStream(sock.getInputStream());
saveFile(sock,dis);
saveFile(sock,dis);
saveFile(sock,dis);
}
}
非常感谢,期待解决此问题:(
通过更改
修复while (fis.read(buffer) > 0) {
outStream.write(buffer);
}
至
int count;
while ((count = fis.read(buffer)) > 0) {
outStream.write(buffer, 0, count);
}
服务器端ClientThread.java内部