在做tcp传输文件实验时,我一直很纠结一个问题,就是Socket客户端发送一个文件SocketServer服务端时,SocketServer只能从socket.getInputStream()中得到一个文件流,怎么才能知道这个文件流具体是什么东西,什么文件,大小多少K等信息呢?思来想去今天有了答案,就是在客户端发送文件时,把文件信息和文件合并后在写入socket输出流。
看上面图,因为SequenceInputStream的参数接收的是InputStream,那怎么把字符串文件信息变成一个读取流呢?假设我的文件信息就是文件名
byte[] info = new byte[512]; 我们规定合并流的前512字节用来保存文件新,这样在服务端就可以先读取前512字节的数据,
byte[] b = filenName.getBytes(); 把文件信息转成字节数组
for(int i=0; i<b.length; i++){ 循环把文件信息的字节填充到预先定义好的用于保存文件信息的字节数组
info[i] = b[i];
}
ByteArrayInputStream bais = new ByteArrayInputStream(info); 用这个流对象对info字节数组进行读取
SequenceInputStream sis = new SequenceInputStream(bais,文件读取流); 合并读取流
这样合并流就完成了,接着把这个合并流写入socket输出流就行了。
完整的代码:
FileCilent客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
import
java.io.BufferedOutputStream;
import
java.io.ByteArrayInputStream;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.SequenceInputStream;
import
java.net.Socket;
public
class
FileClient {
/**
* @param args
*/
public
static
void
main(String[] args) {
try
{
Socket s =
new
Socket(
"192.168.1.100"
,
8800
);
File file =
new
File(
"h:/DPP3.9_60D(1).rar"
);
FileInputStream fs =
new
FileInputStream(file);
//定义一个256字节的区域来保存文件信息。
byte
[] b = file.getName().getBytes();
byte
[] info = Arrays.CopyOf(b,
256
); ByteArrayInputStream bais =
new
ByteArrayInputStream(info);
//合并流
SequenceInputStream sis =
new
SequenceInputStream(bais,fs);
BufferedOutputStream bos =
new
BufferedOutputStream(s.getOutputStream());
byte
[] buf =
new
byte
[
1024
];
int
len =
0
;
while
((len = sis.read(buf))!=-
1
){
bos.write(buf,
0
,len);
}
bos.close();
sis.close();
fs.close();
bais.close();
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
FileServer服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
import
java.io.BufferedInputStream;
import
java.io.BufferedOutputStream;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.net.ServerSocket;
import
java.net.Socket;
import
java.util.concurrent.ExecutorService;
import
java.util.concurrent.Executors;
public
class
FileServer {
/**
* @param args
*/
public
static
void
main(String[] args) {
ExecutorService threadpool = Executors.newFixedThreadPool(
10
);
try
{
ServerSocket ss =
new
ServerSocket(
8800
);
while
(
true
) {
threadpool.execute(
new
UploadThread(ss.accept()));
}
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
class
UploadThread
implements
Runnable {
private
Socket s;
UploadThread(Socket s) {
this
.s = s;
}
@Override
public
void
run() {
System.out.println(s.getInetAddress().getHostAddress());
try
{
BufferedInputStream bis =
new
BufferedInputStream(s.getInputStream());
byte
[] info =
new
byte
[
256
];
bis.read(info);
String file_name =
new
String(info).trim();
BufferedOutputStream bos =
new
BufferedOutputStream(
new
FileOutputStream(
"f:/"
+file_name));
byte
[] buf =
new
byte
[
1024
];
int
len =
0
;
while
((len = bis.read(buf)) != -
1
) {
bos.write(buf,
0
, len);
}
bos.close();
bis.close();
s.close();
System.out.println(file_name+
" 文件传输成功"
);
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
|