伟哥是学C++的,昨天做java老师布置的大作业,让他们做一个文件传输的程序,多线程实现,伟哥很是无语啊,然而他并没有学过太多java,虽然伟哥在我心中是个大神(计算机大神啊,面过了tecent,啧啧),所以找到我帮忙,于是我看了看就想到了前几天刚做的一个http服务器,说白了底层都是使用socket实现的,所以哗啦啦,没有使用异步IO的情况下,用最初的socket写出了多线程的server和client,废话不说,上代码,就是干(前提是先要搞懂对接传输原理)
socket链接不懂的可以去看TCP/IP网络编程,韩国人写的,虽然是用c实现的,但是底层原理已然展现,再用java,so
easy。
首先建立socket连接,通过socket.getInputstream()和getoutputstream()获得socket的输入输出流,这里需要注意的是,很多人分不清in
和out,我说一个个人看法,你要先吧文件读成字节流传给socket吧
(new DataInputStream(new BufferedInputStream(newFileInputStream(fi.getName())));
读),ok然后要向socket里面写吧(new
DataOutputStream(socket.getOutputStream())),首先前后读写函数必须一致,这没问题吧,然后建立连接后,在客户端,你要从socket里面读数据吧,ok
new
DataInputStream(socket.getInputStream())获得读的流,然后你要往文本里面写吧,ok,接着new
DataOutputStream(new BufferedOutputStream(new
FileOutputStream(savePath)))
就是这么easy
上源码:
Server端:
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import .ServerSocket;
import .Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SocketServer {
private ExecutorService executorService =
Executors.newFixedThreadPool(4);// 4个线程;
private ServerSocket ss ;
private Socket socket ;
private DataInputStream dis;
private DataOutputStream ps;
// 处理函数
public void handler(Socket socket) throws IOException {
try {
File fi = new File("abc.txt");
// 读取文件内容
// 通过socket构建输入流
dis = new DataInputStream(new BufferedInputStream(
new FileInputStream(fi.getName())));
// 读取datainputstream的内容
ps = new DataOutputStream(socket.getOutputStream());
// 创建文件输入流
ps.writeUTF(fi.getName());// 文件名字
ps.flush();
ps.writeLong((long) fi.length());// 文件长度
System.out.println((long) fi.length());
ps.flush();
// 创建一个buffer缓冲区
byte[] buffer = new byte[1024];
// 循环读取
while (true) {
int read = 0;
if (dis != null) {
read = dis.read(buffer);
System.out.println("----" + read);
}
if (read == -1) {
// break;
}
ps.write(buffer, 0, read);
ps.flush();
}
} catch (Exception e) {
} finally {
// 关闭连接
dis.close();
ps.close();
socket.close();
System.out.println("文件传输完成");
}
}
// 服务启动项
public void Service() throws IOException {
// 创建一个ServerSocket
ss = new ServerSocket(4500);
System.out.println("服务器启动!");
while (true) {
// 死循环接收
socket = ss.accept();// 使用accept()阻塞等待客户请求
executorService.execute(new Handler(socket));
}
}
// 处理类(内部类)
class Handler implements Runnable {
private Socket socket;
public Handler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
handler(socket);
} catch (Exception e) {
}
}
}
public static void main(String[] args) throws IOException {
// 主函数启动
new SocketServer().Service();
}
}
Client端:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import .Socket;
public class SocketClient {
public static void main(String[] args) {
Socket socket=null;
DataInputStream dis=null;
int passedlen =0;
long len=0;
try {
//创建socket,客户端读取socket数据,byte字节,
socket=new Socket("127.0.0.1", 4500);
//客户端从网络socket的outputstream写数据到文件
dis=new
DataInputStream(socket.getInputStream());//获得socket的读取字节流
String savePath = "E:\\";//读到哪里去
byte[] buf = new byte[1024];//读取字节数
savePath +=
dis.readUTF();
//输出文件地址
DataOutputStream fileOut = new
DataOutputStream(new BufferedOutputStream(new
FileOutputStream(savePath)));
len =
dis.readLong();
System.out.println("文件的长度为:" + len + "\n");
System.out.println("开始接收文件!" + "\n");
while
(true) {
int read = 0;
if (dis!=null) {
read = dis.read(buf);
}
passedlen += read;
if (read == -1) {
break;
}
fileOut.write(buf, 0,
read);
}
System.out.println("接收完成,文件存为" + savePath +
"\n");
fileOut.close();
} catch (Exception e) {
System.out.println("接收消息错误" + "\n");
return;
}
}
}
你可以把Client端多复制几个然后把传过来文件的地址改一下就ok了,我定义线程池里面最多4个线程,就是这样。