java socket传多个文件的疑问?望解答

zg6002 2010-07-02 02:42:34
服务端:ServerSocket server = new ServerSocket(9527);

客房端:Socket socket = new Socket(IP,9527);

问题:传输一个,十个,百个文件都没事,可是现在要传一个文件夹里面有上百万个文件,每次传完一个文件就要重新执行
new Socket(IP,9527);一变,次数多了会有一异常出现,

现在想有没有办法只实现一次new Socket(IP,9527);(把客户端与服务端连接建立后)就利用这一个连接传多个文件?不在for循环里写连接代码?
...全文
661 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
_真真 2012-07-30
  • 打赏
  • 举报
回复
非常感谢16楼的亲情奉献,, 我研究了好久都没弄出来.
阿贝啊啊 2012-04-30
  • 打赏
  • 举报
回复
多谢上面的回答。
tanrenzong1986 2011-07-21
  • 打赏
  • 举报
回复
传输这么多文件,为什么不用FTP啊。
dog12ccc 2011-07-21
  • 打赏
  • 举报
回复
我们的教科书上面也弄错了 客户端是用输出流吧? 服务器是输入流 吧? 是不是哦? 忘记了
guoao_xxL 2011-07-21
  • 打赏
  • 举报
回复
楼上写的 正好需要了!
感谢
kala197 2010-07-05
  • 打赏
  • 举报
回复
嘿嘿ie 顶个 虽然搞Java 但是还没用的过socket
「已注销」 2010-07-05
  • 打赏
  • 举报
回复

发送方
dos.writeInt(files.size());//文件个数
for(File f:files){
dos.writeUTF(f.getName());//文件名
dos.writeLong(f.length());//文件长度
dos.write(...);//文件内容
}

接收方
int n = dis.readInt();//文件个数
for(int i=0;i<n;i++){
String filename = dis.readUTF();//文件名
long length = dis.readLong();//文件长度
dis.read(...);//读取length长度的字节
...//保存文件
}
zg6002 2010-07-05
  • 打赏
  • 举报
回复
发送端用 out.writeUTF("end");表示一份文件完成,开发送下一份文件
接收端:
while((ch = in.read(buf))!=-1) {
len += ch;
DiaInfo.pb1.setValue(len);
DiaInfo.pb1.setString(len+"/"+size);
fos.write(buf,0,ch);
fos.flush();
if("end".equals( in.readUTF())) {
System.out.println("关闭");
break;
}
}
这样写不行了,只要运行到"end".equals( in.readUTF())这句就报错malformed input around byte
应该怎么做标记?
xtuxucj 2010-07-05
  • 打赏
  • 举报
回复
在来一个BteBuffer的,但没实现NIO这个功能。NIO不太会,呵呵。代码没注释,写的很粗糙。就写了基本功能。
客户端

package nioserver;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;

public class ChannelClient {
private SocketChannel sc;
private String hostIp;
private int hostPort;

public ChannelClient(String hostIp, int port) {
this.hostIp = hostIp;
this.hostPort = port;
}

private void setUpConnection() {
try {
SocketAddress remote = new InetSocketAddress(hostIp, hostPort);
sc = SocketChannel.open();
sc.connect(remote);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private void sendFiles(File[] files) {
FileChannel fileChannel = null;
try {
for (int i = 0;i < files.length; i++) {
byte[] namebyte = files[i].getName().getBytes("UTF-8");
long size = files[i].length();
int nameLength = namebyte.length;
fileChannel = new FileInputStream(files[i]).getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.clear();
buffer.putInt(4+8+nameLength);
buffer.putInt(nameLength);
buffer.put(namebyte);
buffer.putLong(size);
buffer.flip();
while(buffer.hasRemaining()){
sc.write(buffer);
}
long count = 1024*1024;
long read = 0L;
while(read < size){
if(size - read < count)
count = size - read;
read += fileChannel.transferTo(0+read, count, sc);
System.out.println("read:"+read);
}
fileChannel.close();
if(i < files.length -1){
sc.write(ByteBuffer.wrap(new byte[]{1}));
System.out.println(1);
}
else
sc.write(ByteBuffer.wrap(new byte[]{0}));
}

sc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
ChannelClient client = new ChannelClient("127.0.0.1", 3000);
client.setUpConnection();
File[] files = new File("D:\\send").listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.isFile();
}
});
client.sendFiles(files);
}

}


服务器端

package nioserver;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class FilesChannelServer {
private String fileName = null;
private long fileSize = 0L;
private int hostPort;
private ServerSocketChannel ssl = null;
private SocketChannel clientChannel = null;
private ByteBuffer buffer = null;

public FilesChannelServer(int port) {
this.hostPort = port;
}

private void setUpConnection() {
try {
ssl = ServerSocketChannel.open();
SocketAddress address = new InetSocketAddress("127.0.0.1", hostPort);
ssl.socket().bind(address);
System.out.println("bind.....");
} catch (IOException e) {
e.printStackTrace();
}
}

private void parseHead(int headlength) {
buffer = ByteBuffer.allocate(headlength);
try {
while(buffer.position() < buffer.capacity())
clientChannel.read(buffer);
buffer.flip();
byte[] filenamebyte = new byte[buffer.getInt()];
buffer.get(filenamebyte);
fileName = new String(filenamebyte,"UTF-8");
fileSize = buffer.getLong();
} catch (IOException e) {
e.printStackTrace();
}
}

private void parseBody(long size) {
long read = 0L;
long count = 8192;
FileChannel fileChannel = null;
try {
fileChannel = new FileOutputStream("D:\\receive\\" + fileName)
.getChannel();
System.out.println(fileName);
while (read < size) {
if (size - read < count)
count = size - read;
read += fileChannel
.transferFrom(clientChannel, 0 + read, count);
}

} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

private int parse() {
int i = 0;
try {
buffer = ByteBuffer.allocate(4);
while(buffer.position() < buffer.capacity())
clientChannel.read(buffer);
buffer.flip();
parseHead(buffer.getInt());
parseBody(fileSize);
buffer = ByteBuffer.allocate(1);
while(buffer.position() < buffer.capacity())
clientChannel.read(buffer);
buffer.flip();
i = buffer.get();
} catch (IOException e) {
e.printStackTrace();
}

return i;
}

private void acceptConnection() {
while (true) {
try {
clientChannel = ssl.accept();
int j = 1;
while(j != 0){
j = parse();
System.out.println(j);
}
} catch (IOException e) {
e.printStackTrace();
} finally {

try {
if (clientChannel != null)
clientChannel.close();
} catch (IOException e) {
e.printStackTrace();
}

}

}
}

public static void main(String[] args) {
FilesChannelServer cs = new FilesChannelServer(3000);
cs.setUpConnection();
cs.acceptConnection();
}
}

这里说明下。可以说是我自定义的协议吧。
一共分成6段
在bytebuffer中第一个4个byte,存放第二段到地四段的byte长度
第二段,四个byte长度是文件名转换成byte数组的长度(file.getName().getBytes("UTF-8").length)
第三段,存放文件名转换的byte(file.getName().getBytes("UTF-8"))
第四段,8个bte存放文件的大小(file.getSize())
第五段,存放文件的byte形式,
第六段,1个byte长度,如果还有后续的文件存放1,如果文件传送完了就存放0
ChDw 2010-07-05
  • 打赏
  • 举报
回复
只要双方都关闭了Socket,那么不应该出现问题的
xtuxucj 2010-07-05
  • 打赏
  • 举报
回复
实在不行就搞个ZipInoutStream。按顺序把文件写到ZipInoutStream中,在另一端解压缩就行。或者自己定义一个解析规定。
贴上我的代码。这个还没整理过。作用是从客服端往服务器端发送文件。
客服端代码

package net;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
* @author Life
*发送文件的客户端
*/
public class FileSendClient {
protected String hostIP;
protected int hostPort;
protected OutputStream socketInS;
private Socket client;

public FileSendClient(String ip, int portNumber) {
this.hostIP = ip;
this.hostPort = portNumber;
}

/**
* 建立连接
*/
public void setUpConnection() {
try {
client = new Socket(hostIP, hostPort);
socketInS = client.getOutputStream();
} catch (UnknownHostException e) {
throw new RuntimeException(e.toString());
} catch (IOException e) {
throw new RuntimeException(e.toString());
}

}

/**
* @param files
* 用zip流发送多个文件
*
*/
public void sendFile(File[] files) {
BufferedInputStream fileReader = null;
ZipOutputStream zos = new ZipOutputStream(socketInS);
BufferedOutputStream socketWriter = new BufferedOutputStream(zos);
byte[] buff = new byte[8192];
int c = 0;
try {
for (File file : files) {
fileReader = new BufferedInputStream(new FileInputStream(file));
zos.putNextEntry(new ZipEntry(file.getName()));
while ((c = fileReader.read(buff)) != -1) {
socketWriter.write(buff, 0, c);
}
socketWriter.flush();
try {
if (fileReader != null)
fileReader.close();
} catch (IOException e) {
System.out.println("Error closing fileReader" + e);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (socketWriter != null )
socketWriter.close();
} catch (IOException e) {
System.out.println("Error closing socketWriter" + e);
}finally{
if(client != null && client.isConnected()){
try {
client.close();
} catch (IOException e) {
System.out.println("Error closing socket" + e);
}
}
}

}

}

public static void main(String[] args) {
FileSendClient fileSendClient = new FileSendClient("127.0.0.1", 3000);
fileSendClient.setUpConnection();
File[] files = new File("D:\\send").listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.isFile();
}
});
fileSendClient.sendFile(files);

}
}

服务器端代码:

package net;

import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;


/**
* @author Life
*文件接收服务器
*/
public class FileReceiveServer {
protected int listenPort;
private int maxConnection;

public FileReceiveServer(int listenPort,int maxConnection) {
this.listenPort = listenPort;
this.maxConnection = maxConnection;
}

/**
* 建立监听端口
*/
public void setUpConnection(){
for(int i = 0; i < maxConnection; i++){
new Thread(new FileReceiverHandle(),"handle"+i).start();
}


}

/**
* 接收文件客户端的连接
*/
public void acceptConnection() {
try {
ServerSocket server = new ServerSocket(listenPort);
Socket incomingSocket = null;
while (true) {
incomingSocket = server.accept();
handlerConnection(incomingSocket);
}
} catch (BindException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

/**
* @param incomingSocket
* 处理接收到的连接(socket)
*/
private void handlerConnection(Socket incomingSocket) {
FileReceiverHandle.processConnection(incomingSocket);

}

public static void main(String[] args) {
FileReceiveServer fileReceiveServer = new FileReceiveServer(3000,5);
fileReceiveServer.setUpConnection();
fileReceiveServer.acceptConnection();
}

}



package net;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
* @author Life
*文件接收处理程序
*/
public class FileReceiverHandle implements Runnable {
private static List<Socket> socketsPool = new LinkedList<Socket>();
private Socket connection = null;

/**
* @param incomingSocket
* 降接收到的连接放到一个池中
*
*/
public static void processConnection(Socket incomingSocket) {
synchronized (socketsPool) {
socketsPool.add(socketsPool.size(), incomingSocket);
socketsPool.notifyAll();
}
}

/**
* 按zip流解码获取接收到的流
*/
public void handlerConnection() {
InputStream inputFromSocket = null;
BufferedOutputStream fileWriter = null;
BufferedInputStream socketReader = null;
byte[] buff = new byte[8192];
int c = 0;
try {
inputFromSocket = connection.getInputStream();
ZipInputStream zis = new ZipInputStream(inputFromSocket);
socketReader = new BufferedInputStream(zis);
ZipEntry e = null;
while ((e = zis.getNextEntry()) != null) {
System.out.println(e.getName());
fileWriter = new BufferedOutputStream(new FileOutputStream(
new File("D:\\receive\\" + e.getName())));
while ((c = socketReader.read(buff)) != -1) {
fileWriter.write(buff, 0, c);
}
try {
fileWriter.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (socketReader != null) {
socketReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try{
if(connection != null){
connection.close();
}
}catch(IOException e){
e.printStackTrace();
}
}

}
}

/*
* 处理池中的连接
*/
public void run() {
while (true) {
synchronized (socketsPool) {
while (socketsPool.isEmpty()) {
try {
socketsPool.wait();
} catch (InterruptedException e) {
return;
}
}
connection = socketsPool.remove(socketsPool.size() - 1);
}
handlerConnection();
}
}

}
guobaoaskformore 2010-07-02
  • 打赏
  • 举报
回复
自己设置一个文件分隔标识吧,搞复杂一些,当发送一个文件结束后,将该分隔标识发出去,客户端读到这一行就表示一个文件结束,则开始读取下个文件
如果觉得土,可以看看,一些FTP的源码如何处理的。
zg6002 2010-07-02
  • 打赏
  • 举报
回复
现在的问题就是怎么判断什么时候发送完一个文件,什么时候开始接收下一个文件
zuoguodang 2010-07-02
  • 打赏
  • 举报
回复
连一次啊,发文件就是遍历文件一个一个的发
俊哥123 2010-07-02
  • 打赏
  • 举报
回复
无论是发送还是接受方都不要重复的new socket,
第一次使用时判断是否为空,为空才new,所有的任务做完了,才能关闭。
你把握这一点,程序就OK了

用while(true){
Thread.sleep(1000l);
if(inputStream.available()>0){
//判断有数据过来,接收

}
}
zg6002 2010-07-02
  • 打赏
  • 举报
回复
发送方:int t = 0;
while((ch = fis.read(buf))!=-1) {
t += ch;
out.write(buf,0,ch);
if(t == (int)f.length()) {
break;
}
}


接收方:while((ch = in.read(buf))!=-1) {
len += ch;
DiaInfo.pb1.setValue(len);
DiaInfo.pb1.setString(len+"/"+size);
fos.write(buf, 0, ch);
if(len == size) {
break;
}
}
zg6002 2010-07-02
  • 打赏
  • 举报
回复
发送端和接收端都有一个while循环 通过in.read(buf))!=-1退出
如果不重新连一下服务,用一个连接的话,发送端和接收端怎么判断什么时候接收新的文件?
prince_java 2010-07-02
  • 打赏
  • 举报
回复
你不会把Socket写在for循环里了吧- -!
客户端就写一个Socket连接,用BufferedReader从键盘接收你要传的文件或文件夹,然后用if进行判断,如果你要传的类型是文件,那好,直接用输入输出流进行复制,如果是文件夹,那就用for循环对文件夹进行遍历,是文件就复制文件,是文件夹的就按照文件夹的名字新建文件夹
俊哥123 2010-07-02
  • 打赏
  • 举报
回复
你这样老new socket,再牛逼的电脑,连接缓存都要搞没了
你在外面定义好一个socket,和输入输出流
new 一次,以后重用
所有文件发完了再关闭。
magicbu 2010-07-02
  • 打赏
  • 举报
回复
为什么要重新执行new Socket(IP,9527)
好像没必要吧~
加载更多回复(1)
Java版精华区
java jsp及js等精华帖子合集
适合收藏 查询

序号 精华区主题
--------------------------------
1. [目录]Java教程
1. [目录]Java语言教程
2. [目录]来自java
3. [目录]咖啡备忘录
4. [目录]Java介绍
5. [目录]Java学习笔记(推荐)
6. [目录]JDBC文档
7. [目录]RMI 文档
2. [目录]Java资源(文档-书籍-下载-注册码)
1. [目录]License 和注册码
2. [目录]好书推荐
3. [目录]关于Java的一些Mail List
4. [目录]CORBA资源
5. [目录]Linux下的Java
24. [目录]以前介绍的资源
25. [目录]Java编程工具
30. [目录]更多下载相关
3. [目录]JavaScript
1. [目录]javascript 书籍
2. [目录]javascript 书籍(2)
4. [目录]术语字典
5. [目录]Java编程
1. [目录]Java简单问题
2. [目录]为什么Applet修改后在浏览器中不发生变化
3. [目录]Java中的类型转换
4. [目录]怎样找到编译时缺少的类
2. [目录]Java疑难解答
1. [目录]Java原理问题
1. [目录]Java中是指针还是引用?
2. [目录]关于getMethod方法
3. [目录]怎样建立Package
4. [目录]关于classloader
2. [目录]Java汉字问题
3. [目录]Java中的界面处理
1. [目录]Java中的鼠标操作
2. [目录]如何使画面不闪烁?
4. [目录]Java与Internet
1. [目录]Socket方面的疑问
2. [目录]用plag-in运行Applet with JDK 1.2
5. [目录]Java访问数据库
1. [目录]一个JDBC问题
6. [目录]Java安全性问题
1. [目录]数字化签名
1. [目录]JAVAKEY问题
7. [目录]Java与Linux
8. [目录]Java其他问题
1. [目录]播放.au文件的问题
2. [目录]RMI
11. [目录]线程问题
12. [目录]Java打印
13. [目录]本地相关问题(JNI,串口等)
3. [目录]Java编程实例
1. [目录]Java 实 例
2. [目录]Java applet中的动画
17. [目录]Java串口实例
4. [目录]Java3D专题介绍
5. [目录]Java与开发工具
1. [目录]关于JBuilder的问题
2. [目录]Jbuilder安装与使用中的常见问题
7. [目录]Java编程工具
8. [目录]Visual Age for Java
9. [目录]Websphere
7. [目录]Applet专题(安全,通信)
1. [目录]Applet的安全限制及措施
2. [目录]与Servlet通信
3. [目录]与其他Cgi程序通信
4. [目录]与JavaScript通信
5. [目录]与其他Applet通信
6. [目录]找不到类的问题
6. [目录]Java动态与讨论
1. [目录]Java最新动态
9. [目录]面向对象的骡子
13. [目录]JSP+Bean?
14. [目录]牢骚
15. [目录]Java之争 - 谁最吃亏
17. [目录]真成JAVA大牛还是很有前途的
18. [目录]Jbuilder及Swing,多线程问题讨论
7. [目录]快乐Java大家谈
1. [目录]活动简介
2. [目录]庆祝专区
3. [目录]dW站点简介
4. [目录]待审稿件
5. [目录]已审稿件
6. [目录]整理精华区
7. [目录]建议和投票
8. [目录]临时目录
9. [目录]活动征文
10. [目录]人物趣事
8. [目录]java server技术
1. [目录]中文问题
2. [目录]JSP 和Servlet
1. [目录]JSP语法
2. [目录]JSP的安全问题
3. [目录]查询结果的分页显示
4. [目录]CGI,mod_perl,PHP,JSP比较
3. [目录]线程池的讨论
4. [目录]JDBC
5. [目录]EJB技术
1. [目录]EJB 的设计模式
6. [目录]Servlet Container 和 应用服务器
3. [目录]TOMCAT
9. [目录]纪念光盘精华区精选目录
1. [目录]Java编程
1. [目录]Java简单问题
2. [目录]为什么Applet修改后在浏览器中不发生变化
3. [目录]Java中的类型转换
4. [目录]怎样找到编译时缺少的类
2. [目录]Java疑难解答
1. [目录]Java原理问题
1. [目录]Java中是指针还是引用?
2. [目录]关于getMethod方法
3. [目录]怎样建立Package
4. [目录]关于classloader
2. [目录]Java汉字问题
3. [目录]Java中的界面处理
1. [目录]Java中的鼠标操作
2. [目录]如何使画面不闪烁?
4. [目录]Java与Internet
1. [目录]Socket方面的疑问
2. [目录]用plag-in运行Applet with JDK 1.2
5. [目录]Java访问数据库
1. [目录]一个JDBC问题
6. [目录]Java安全性问题
1. [目录]数字化签名
1. [目录]JAVAKEY问题
7. [目录]Java与Linux
8. [目录]Java其他问题
1. [目录]播放.au文件的问题
2. [目录]RMI
11. [目录]线程问题
12. [目录]Java打印
3. [目录]Java编程实例
1. [目录]Java 实 例
2. [目录]Java applet中的动画
4. [目录]Java3D专题介绍
5. [目录]Java与开发工具
1. [目录]关于JBuilder的问题
6. [目录]Java编程工具
7. [目录]Visual Age for Java
8. [目录]Websphere
7. [目录]Applet
2. [目录]Java动态与讨论
1. [目录]Java最新动态
9. [目录]面向对象的骡子
13. [目录]JSP+Bean?
3. [目录]java server技术
1. [目录]中文问题
29. [目录]线程池的讨论
30. [目录]JDBC
31. [目录]JSP语法
32. [目录]EJB
33. [目录]TOMCAT
34. [目录]JSP的安全问题
35. [目录]查询结果的分页显示
10. [目录]老精华区文章
1. [目录]Active X编程
2. [目录]Active X介绍

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧