请问基于C/S下的局域网文件传输,在客户端采用多线程下载一个文件的时候,socket流那里应该做什么处理~服务器先从硬盘读取文件数据,然后向socket流写入数据,客户端启动多个线程和server连接,server这边要怎么去处理?服务器用DataInputStream流先读文件,再用DataOutputStream写入socket流中,客户端的多线程代码应该没问题,在本机上直接读文件不经过socket流写入的时候再写入到别的位置的时候能正常运行,现在是经过了socket流后出现问题了~新手求教~
发点代码,顺便把异常贴出来
brf = new BufferedRandomAccessFile((String) ServerFrame.jt4
.getValueAt(index, 0), "rw"); // 用带缓冲的RandomAccessFile读取硬盘数据 long length = ((File) ServerFrame.list.get(index)) //读取要下载的文件的长度
.length(); dos.writeLong(length); dos.flush(); byte[] buf = new byte[8192]; System.out.println("right here");
int check = 0; while (true) {
int read = 0;
read = brf.read(buf);
if (read == -1) {
break;
}
dos.write(buf, 0, read);
}
dos.flush();
dos = this.getDataOutputStream(socket);
dos.writeInt(index);
dos.flush(); // 文件索引
ois = this.getObjectInputStream(socket);
dis = this.getDataInputStream(socket);
long length = dis.readLong(); // 读取要下载的文件的总长度 SpiltFile sf=new
SpiltFile(serverIpAndPort,f,5,length,jfc);
sf.start();
public class SpiltFile extends Thread { private long[] StartPos;
private long[] EndPos;
private int count;
private DataOutputStream output;
private boolean Stop = false;
private File f;
private DowndSubThread downSubThread[];
private long length;
private JFileChooser jfc;
private ServerIPAndPort serverIpAndPort; public SpiltFile(ServerIPAndPort serverIpAndPort,File f,int count,long length,JFileChooser jfc) throws InterruptedException {
this.count = count;
this.length=length;
this.jfc=jfc;
this.f=f;
this.serverIpAndPort=serverIpAndPort;
} public void run() {
try { StartPos = new long[count];
EndPos = new long[count]; for (int i = 0; i < StartPos.length; i++) {
StartPos[i] = (long) (i * (length / StartPos.length));
}
for (int i = 0; i < EndPos.length - 1; i++) {
EndPos[i] = StartPos[i + 1];
}
EndPos[EndPos.length - 1] = length; DowndSubThread downSubThread[] = new DowndSubThread[count];
for (int i = 0; i < StartPos.length; i++) { downSubThread[i] = new DowndSubThread(serverIpAndPort,f,
jfc.getSelectedFile().getPath(), StartPos[i],
EndPos[i], i);
downSubThread[i].start(); } boolean breakWhile = false;
while (!Stop) {
breakWhile = true;
for (int i = 0; i < StartPos.length; i++) {
if (!downSubThread[i].DownOver) {
breakWhile = false;
break;
}
}
if (breakWhile)
break;
}
System.out.println("文件下载完毕");
} catch (Exception e) {
e.printStackTrace();
}
}
}
[/code]
[code=Java]
public class DowndSubThread extends Thread { public long nStart, nEnd;
private int id;
private boolean Stop = false;
public boolean DownOver = false;
private File f;
private GetFileDown getFile;
private Socket socket;
private ServerIPAndPort serverIpAndPort;
private String ip;
private int port; public DowndSubThread(ServerIPAndPort serverIpAndPort, File f, String savePath, long nStart,
long nEnd, int id) throws IOException {
this.f = f;
this.nStart = nStart;
this.nEnd = nEnd;
this.id = id;
this.serverIpAndPort=serverIpAndPort;
this.getFile = new GetFileDown(savePath, nStart);
} public void run() {
while (nStart < nEnd && !Stop) {
try {
//获取和服务器的连接
ip = serverIpAndPort.getIp();
InetAddress ipServer = InetAddress.getByName(ip); port = Integer.parseInt(serverIpAndPort.getPort()); socket = new Socket(ipServer, port); DataInputStream dis = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
//读取socket中的数据写入硬盘 byte[] b = new byte[8192];
int Read;
while ((Read = dis.read(b, 0, 8192)) > 0 && nStart < nEnd
&& !Stop) {
nStart += getFile.write(b, 0, Read);
}
DownOver = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}}[/code]
public class GetFileDown implements Serializable {
BufferedRandomAccessFile getFile;
long seekPos; public GetFileDown(String savePath, long seekPos) throws IOException {
getFile = new BufferedRandomAccessFile(savePath, "rw");
this.seekPos = seekPos;
getFile.seek(seekPos);
}
public synchronized int write(byte[] b, int nStart, int Length) throws IOException {
int read = -1;
try {
getFile.write(b, nStart, Length);
read = Length;
} catch (IOException e) {
e.printStackTrace();
}
return read;
}
}
final int totalParts = 5;
new Thread() { @Override
public void run() {
ServerSocket ss = null;
try {
ss = new ServerSocket(8080);
for (int i = 0; i < totalParts; i++) {
new Thread(new Send(ss.accept())).start();
}
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (ss != null) {
try {
ss.close();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}.start();
Thread.yield();
new Down("localhost", 8080, "c:\\test.png", totalParts).startDown(new File("c:\\test01.png"));
} public static void closeIO(Closeable io) {
if (io != null) {
try {
io.close();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
} public static class Down implements Runnable { public Down(String host, int port, String requestFile, int totalParts) {
this.host = host;
this.port = port;
this.requestFile = requestFile;
this.totalParts = totalParts;
part = new AtomicInteger(totalParts);
} public void startDown(File localFile) throws FileNotFoundException, InterruptedException {
try {
fileWrite = new RandomAccessFile(localFile, "rw");
Thread[] ts = new Thread[totalParts];
for (int i = 0; i < ts.length; i++) {
ts[i] = new Thread(this);
ts[i].start();
}
for (int i = 0; i < ts.length; i++) {
ts[i].join();
}
} finally {
closeIO(fileWrite);
}
} public void run() {
Socket s = null;
try {
s = new Socket(host, port);
DataOutputStream send = new DataOutputStream(s.getOutputStream());
/* 写入头 */ {
send.writeUTF(requestFile);
send.writeInt(totalParts);
send.writeInt(part.getAndDecrement());
send.flush();
}
DataInputStream read = new DataInputStream(s.getInputStream());
long fileLength = read.readLong();
synchronized (this) {
if (fileLength != fileWrite.length()) {
fileWrite.setLength(fileLength);
}
}
long seek = read.readLong();
byte[] buff = new byte[128 * 1024];
for (int i = read.read(buff); i >= 0; i = read.read(buff)) {
synchronized (this) {
fileWrite.seek(seek);
fileWrite.write(buff, 0, i);
}
seek += i;
}
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
s.close();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private String host;
private int port;
private String requestFile;
private int totalParts;
private RandomAccessFile fileWrite;
private AtomicInteger part;
} public static class Send implements Runnable { public Send(Socket s) {
this.s = s;
} public void run() {
FileInputStream fileRead = null;
try {
DataInputStream read = new DataInputStream(s.getInputStream());
DataOutputStream send = new DataOutputStream(s.getOutputStream());
/* 每部分文件的最大长度 */
long x = 0;
/* 计算并发送头 */ {
File f = new File(read.readUTF());
long fileLength = f.length();
x = fileLength / read.readInt();
long seek = x * (read.readInt() - 1);
send.writeLong(fileLength);
send.writeLong(seek);
send.flush();
fileRead = new FileInputStream(f);
fileRead.skip(seek);
}
byte[] buff = new byte[128 * 1024];
for (int i = fileRead.read(buff); i >= 0; i = fileRead.read(buff)) {
/* 如果刚刚读完或者读超了,则写入合理的长度,并退出 */
if (x <= i) {
send.write(buff, 0, (int) (x));
break;
} else {
send.write(buff, 0, i);
}
x -= i;
}
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
s.close();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
closeIO(fileRead);
}
}
private Socket s;
}
}