在将此标记为可能重复之前,请先阅读一次,因为我无法找到任何答案。我正在学习Socket编程并使用套接字创建非常基本的服务器 - 客户端文件传输程序。 这是我的服务器模块:
import java.io.*;
import java.net.*;
import static java.lang.System.out;
public class ServerMain {
public static void main(String[] args) {
int PORT=13267;
ServerSocket servSocket;
Socket client;
File source=new File("E:/Styles of Beyond.wav");;
BufferedInputStream bis;
BufferedReader br;
String s="";
InputStream is;
byte[] byteBuffer=new byte[10240];
OutputStream os;
int count=0;
try{
servSocket=new ServerSocket(PORT);
out.println("Server running on port: "+PORT+", waiting for client...");
client=servSocket.accept();
client.setKeepAlive(true);
out.println("Client: "+client.getRemoteSocketAddress()+" connected. Sending file...");
bis=new BufferedInputStream(new FileInputStream(source));
os=client.getOutputStream();
is=client.getInputStream();
while((count=bis.read(byteBuffer))>0){
os.write(byteBuffer, 0, count);
}
out.println("Waiting for confirmation from client...");
br=new BufferedReader(new InputStreamReader(is));
if(br.readLine()=="Done")
out.println("Done.");
else
out.println("Couldn't get confirmation from server.");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
客户端模块:
import static java.lang.System.out;
import java.io.*;
import java.net.*;
public class ClientMain {
public static void main(String[] args) {
int SERV_PORT=13267;
Socket server;
File destination=new File("E:/copy.wav");
byte[] byteBuffer=new byte[10240];
InputStream is;
OutputStream os;
BufferedWriter bw;
int count=0;
try{
out.println("Tyring to connect to server...");
server=new Socket("localhost",SERV_PORT);
out.println("Connected to server: "+server.getRemoteSocketAddress());
is=server.getInputStream();
os=server.getOutputStream();
out.println("Receiving data...");
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(destination));
while((count=is.read(byteBuffer))>0){
bos.write(byteBuffer, 0, count);
}
bw=new BufferedWriter(new OutputStreamWriter(os));
bw.write("Done");
bw.newLine();
out.println("Data successfully written to copy.wav");
}
catch(Exception e){
e.printStackTrace();
}
}
}
代码工作,甚至文件copy.wav都是正确创建的,但是在客户端的操作系统上写完后,服务器就会卡在"等待来自客户端的确认...",并且客户端是卡在"接收数据......"。我尝试在客户端使用PrintWriter而不是BufferedWriter,并且还尝试在os上编写单个字节,并在服务器端检查该字节是否为文件接收确认,但似乎没有任何效果,客户端没有发送任何内容。我注意到的一件事是在服务器上调用is.ready()总是返回false。
如果我删除了与发送和接收客户端上的文件确认相关的所有代码。服务器,客户端程序生成SocketException:连接重置,因为现在服务器没有等待客户端完成其is.read()任务,并在使用os.write()完成写入后立即关闭连接,创建copy.wav,其部分数据的大小小于原始数据。我该怎么做呢?
P.S:我知道我没有关闭流并正确处理异常,但这似乎不是问题。答案 0 :(得分:2)
冲洗它!
https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html#flush()
打电话后:
bw.write("Done");
bw.newLine();
操作系统正在等待更多,因此它可以有效地将数据发送到一大块。
此外,您可以在其上设置TCP_NODELAY,但通常应该让操作系统执行此操作,因为在大多数情况下,它比您更了解发送数据的最佳方式。