【发布时间】:2016-10-12 09:03:02
【问题描述】:
在将此标记为可能重复之前,请先阅读一次,因为我找不到任何答案。我正在学习套接字编程并使用套接字创建一个非常基本的服务器-客户端文件传输程序。 这是我的服务器模块:
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也可以正确创建,但是在客户端的操作系统上写入后,服务器卡在“等待来自客户端的确认...”,客户端卡在“正在接收数据。 ……”。我尝试在客户端而不是 BufferedWriter 上使用 PrintWriter,并且还简单地尝试在 os 上写入单个字节,并在服务器端检查该字节以获取文件接收确认,但似乎没有任何效果,客户端没有发送任何内容。我注意到的一件事是,在服务器上调用 is.ready() 总是返回 false。
如果我在客户端和服务器上删除与发送和接收文件确认相关的所有代码,客户端程序会产生 SocketException: connection reset,因为现在服务器不会等待客户端完成其 is.read( ) 任务并在使用 os.write() 完成写入后立即关闭连接,这会创建具有小于原始数据大小的部分数据的 copy.wav。我该如何正确地做这件事?
P.S:我知道我没有关闭流并正确处理异常,但这似乎不是问题。
【问题讨论】:
-
您不能在同一个套接字上混合缓冲流和读取器。他们会互相窃取数据。
-
@EJP 那么我应该在使用另一个之前关闭一个吗?
-
我不明白投反对票的原因,问题还没有解决,下面发布的答案 xaxxon 对我不起作用......
-
所以你应该使用其中一个。正如我已经说过的,不要混合它们。
标签: java sockets outputstream