socket client传文件到server,server端接收成功后给客户端反馈一个信息
2013-05-15 19:58
567 查看
java server接收文件后返回字符串给client
客户端:
/* 通讯
需求:传送任意文件
tcp传输要定义2个端点,客户端和服务端
步骤
1.定义服务, 服务器ip和接收端口
2.读取客户端已有的图片文件
3.使用socket输出流将数据发给服务端
4.读取服务端的反馈信息
5.关闭资源
注意:
1.在while循环中的read方法最后读到文件结束标记-1后循环退出了
而没有将该标记写入socket流中,那么服务端接收到的数据是不完整的,而且停不下来
用shutdownOutput方法告诉服务端文件到了末尾结束发送了
[示例]:传送任意文件 (客户端)
*/
import java.net.*;
import java.io.*;
class Demo
{
public static void main(String[] args) throws Exception
{
new FileClient("c:\\FoxitReader_CHS.rar"); //启动客户端,准备发送指定文件
}
}
class FileClient //客户端
{
FileClient(String fileStr) throws Exception
{
s.op("客户端启动....");
File file = new File(fileStr); //关联一个文件c:\\FoxitReader_CHS.rar
if(file.isFile()) //是一个标准文件吗?
{
client(file); //启动连接
}
else
{
s.op("要发送的文件 "+fileStr+" 不是一个标准文件,请正确指定");
}
}
public void client(File file)throws Exception
{
Socket sock= new Socket("192.168.1.3",10007); //指定服务端地址和端口
FileInputStream fis = new FileInputStream(file); //读取本地文件
OutputStream sockOut = sock.getOutputStream(); //定义socket输出流
//先发送文件名.让服务端知道
String fileName = file.getName();
s.op("待发送文件:"+fileName);
sockOut.write(fileName.getBytes());
String serverInfo= servInfoBack(sock); //反馈的信息:服务端是否获取文件名并创建文件成功
if(serverInfo.equals("FileSendNow")) //服务端说已经准备接收文件,发吧
{
byte[] bufFile= new byte[1024];
int len=0;
while(true)
{
len=fis.read(bufFile);
if(len!=-1)
{
sockOut.write(bufFile,0,len); //将从硬盘上读取的字节数据写入socket输出流
}
else
{
break;
}
}
}
else
{
s.op("服务端返回信息:"+serverInfo);
}
sock.shutdownOutput(); //必须的,要告诉服务端该文件的数据已写完
s.op("服务端最后一个返回信息:"+servInfoBack(sock));//显示服务端最后返回的信息
fis.close();
sock.close();
}
public String servInfoBack(Socket sock) throws Exception //读取服务端的反馈信息
{
InputStream sockIn = sock.getInputStream(); //定义socket输入流
byte[] bufIn =new byte[1024];
int lenIn=sockIn.read(bufIn); //将服务端返回的信息写入bufIn字节缓冲区
String info=new String(bufIn,0,lenIn);
return info;
}
}
class s
{
public static void op(Object obj) //打印
{
System.out.println(obj);
}
}
服务端:
/*
服务端原先有很大的局限性
原先我们没有考虑客户端的文件名,和客户端判断是否有重名文件,我们是另外指定了文件名和路径
当客户端A连接服务端,被服务端获取到后,服务端执行具体流程,
这时如果B客户端尝试连接服务端,但只能等待
因为服务端还没有处理完A客户端的请求,不能回while起始位置执行accept方法,所以
暂时获取不到B客户端对象,那么为了可以让多个客户端同时被服务端并发接收,
那么服务端最好就是将每个客户端封装到一个个单独的线程中,这样,就可以同时处理多个客户端请求
如何定义线程呢?
只要明确每一个客户端要再服务端执行的代码即可,将该代码放到run方法中
如果服务端存在同名文件就返回信息并断开该次连接
如果要让客户端选择是否要覆盖文件,可以再加个反馈操作应该就可以了
[示例]:传送任意文件 (服务端并发执行)
*/
import java.net.*;
import java.io.*;
class Demo
{
public static void main(String[] args) throws Exception
{
new FileServer(); //启动文件存储服务端
}
}
class FileServer //服务端
{
FileServer() throws Exception
{
s.op("服务端启动......");
server();
}
public void server() throws Exception
{
ServerSocket serversock = new ServerSocket(10007); //监听端口
while(true)
{
Socket sock = serversock.accept(); //循环等待客户端连接
new Thread(new FileServThread(sock)).start(); //当成功连接客户端后开启新线程接收文件
}
}
}
class FileServThread implements Runnable //服务端线程
{
private Socket sock;
FileServThread(Socket sock)
{
this.sock = sock;
}
public void run()
{
String ip = sock.getInetAddress().getHostAddress(); //获取客户端ip
try
{
s.op("开启新线程接收来自客户端IP: "+ip+" 的文件");
InputStream sockIn= sock.getInputStream();//定义socket输入流,接收客户端的信息
File file =getClientFileName(sockIn); //创建同名文件
if(file==null)
{
writeOutInfo(sock,"存在同名文件或获取文件失败,服务端断开连接!");
sock.close(); return;
}
FileOutputStream fos= new FileOutputStream(file); //用来写入硬盘
byte[] bufFile = new byte[1024*1024]; //接收数据的缓存
int len=0;
while(true)
{
len=sockIn.read(bufFile); //接收数据
if(len!=-1)
{
fos.write(bufFile,0,len); //写入硬盘文件
}
else
{
break;
}
}
writeOutInfo(sock,"上传成功!"); //文件接收成功后给客户端反馈一个信息
s.op("文件接收成功!"+System.getProperty("line.separator")); //服务端打印一下
fos.close();
sock.close();
}
catch(Exception ex)
{
throw new RuntimeException(ip+"异常!!!");
}
}
public void writeOutInfo(Socket sock,String infoStr)throws Exception//将信息反馈给服务端
{
OutputStream sockOut = sock.getOutputStream();
sockOut.write(infoStr.getBytes());
}
public File getClientFileName(InputStream sockIn) throws Exception //获取文件名并创建
{
//获取客户端请求发送的文件名,并判断在D盘创建同名文件的情况
byte[] bufName=new byte[1024];
int lenInfo =0;
lenInfo = sockIn.read(bufName); //获取文件名
String fileName = new String(bufName,0,lenInfo);
File dir = new File("d:\\"); //存到D盘根目录
File[] files=dir.listFiles(); //遍历d盘目录
for(File f:files)
{
if(!f.isDirectory()) //如果遍历到的该文件不是一个目录的话
{
if(f.getName().equals(fileName)) //判断是否是同名文件
{
s.op(f.getName()+"文件已存在,断开该ip连接."+System.getProperty("line.separator"));
writeOutInfo(sock,"服务端已存在同名文件!"); //反馈给客户端的信息
return null;
}
}
}
s.op("将客户端发来的文件( "+fileName+" )存到"+dir.getAbsolutePath());
File file= new File(dir+fileName);
if(file.createNewFile())
{
s.op("成功创建文件("+fileName+" )准备写入数据");
writeOutInfo(sock,"FileSendNow"); //告诉客户端,开始传送数据吧
return file;
}
else
{
return null; //如果由于硬盘满了等原因创建文件失败的话
}
}
}
class s
{
public static void op(Object obj) //打印
{
System.out.println(obj);
}
}
http://xouou.iteye.com/blog/1387875
客户端:
/* 通讯
需求:传送任意文件
tcp传输要定义2个端点,客户端和服务端
步骤
1.定义服务, 服务器ip和接收端口
2.读取客户端已有的图片文件
3.使用socket输出流将数据发给服务端
4.读取服务端的反馈信息
5.关闭资源
注意:
1.在while循环中的read方法最后读到文件结束标记-1后循环退出了
而没有将该标记写入socket流中,那么服务端接收到的数据是不完整的,而且停不下来
用shutdownOutput方法告诉服务端文件到了末尾结束发送了
[示例]:传送任意文件 (客户端)
*/
import java.net.*;
import java.io.*;
class Demo
{
public static void main(String[] args) throws Exception
{
new FileClient("c:\\FoxitReader_CHS.rar"); //启动客户端,准备发送指定文件
}
}
class FileClient //客户端
{
FileClient(String fileStr) throws Exception
{
s.op("客户端启动....");
File file = new File(fileStr); //关联一个文件c:\\FoxitReader_CHS.rar
if(file.isFile()) //是一个标准文件吗?
{
client(file); //启动连接
}
else
{
s.op("要发送的文件 "+fileStr+" 不是一个标准文件,请正确指定");
}
}
public void client(File file)throws Exception
{
Socket sock= new Socket("192.168.1.3",10007); //指定服务端地址和端口
FileInputStream fis = new FileInputStream(file); //读取本地文件
OutputStream sockOut = sock.getOutputStream(); //定义socket输出流
//先发送文件名.让服务端知道
String fileName = file.getName();
s.op("待发送文件:"+fileName);
sockOut.write(fileName.getBytes());
String serverInfo= servInfoBack(sock); //反馈的信息:服务端是否获取文件名并创建文件成功
if(serverInfo.equals("FileSendNow")) //服务端说已经准备接收文件,发吧
{
byte[] bufFile= new byte[1024];
int len=0;
while(true)
{
len=fis.read(bufFile);
if(len!=-1)
{
sockOut.write(bufFile,0,len); //将从硬盘上读取的字节数据写入socket输出流
}
else
{
break;
}
}
}
else
{
s.op("服务端返回信息:"+serverInfo);
}
sock.shutdownOutput(); //必须的,要告诉服务端该文件的数据已写完
s.op("服务端最后一个返回信息:"+servInfoBack(sock));//显示服务端最后返回的信息
fis.close();
sock.close();
}
public String servInfoBack(Socket sock) throws Exception //读取服务端的反馈信息
{
InputStream sockIn = sock.getInputStream(); //定义socket输入流
byte[] bufIn =new byte[1024];
int lenIn=sockIn.read(bufIn); //将服务端返回的信息写入bufIn字节缓冲区
String info=new String(bufIn,0,lenIn);
return info;
}
}
class s
{
public static void op(Object obj) //打印
{
System.out.println(obj);
}
}
服务端:
/*
服务端原先有很大的局限性
原先我们没有考虑客户端的文件名,和客户端判断是否有重名文件,我们是另外指定了文件名和路径
当客户端A连接服务端,被服务端获取到后,服务端执行具体流程,
这时如果B客户端尝试连接服务端,但只能等待
因为服务端还没有处理完A客户端的请求,不能回while起始位置执行accept方法,所以
暂时获取不到B客户端对象,那么为了可以让多个客户端同时被服务端并发接收,
那么服务端最好就是将每个客户端封装到一个个单独的线程中,这样,就可以同时处理多个客户端请求
如何定义线程呢?
只要明确每一个客户端要再服务端执行的代码即可,将该代码放到run方法中
如果服务端存在同名文件就返回信息并断开该次连接
如果要让客户端选择是否要覆盖文件,可以再加个反馈操作应该就可以了
[示例]:传送任意文件 (服务端并发执行)
*/
import java.net.*;
import java.io.*;
class Demo
{
public static void main(String[] args) throws Exception
{
new FileServer(); //启动文件存储服务端
}
}
class FileServer //服务端
{
FileServer() throws Exception
{
s.op("服务端启动......");
server();
}
public void server() throws Exception
{
ServerSocket serversock = new ServerSocket(10007); //监听端口
while(true)
{
Socket sock = serversock.accept(); //循环等待客户端连接
new Thread(new FileServThread(sock)).start(); //当成功连接客户端后开启新线程接收文件
}
}
}
class FileServThread implements Runnable //服务端线程
{
private Socket sock;
FileServThread(Socket sock)
{
this.sock = sock;
}
public void run()
{
String ip = sock.getInetAddress().getHostAddress(); //获取客户端ip
try
{
s.op("开启新线程接收来自客户端IP: "+ip+" 的文件");
InputStream sockIn= sock.getInputStream();//定义socket输入流,接收客户端的信息
File file =getClientFileName(sockIn); //创建同名文件
if(file==null)
{
writeOutInfo(sock,"存在同名文件或获取文件失败,服务端断开连接!");
sock.close(); return;
}
FileOutputStream fos= new FileOutputStream(file); //用来写入硬盘
byte[] bufFile = new byte[1024*1024]; //接收数据的缓存
int len=0;
while(true)
{
len=sockIn.read(bufFile); //接收数据
if(len!=-1)
{
fos.write(bufFile,0,len); //写入硬盘文件
}
else
{
break;
}
}
writeOutInfo(sock,"上传成功!"); //文件接收成功后给客户端反馈一个信息
s.op("文件接收成功!"+System.getProperty("line.separator")); //服务端打印一下
fos.close();
sock.close();
}
catch(Exception ex)
{
throw new RuntimeException(ip+"异常!!!");
}
}
public void writeOutInfo(Socket sock,String infoStr)throws Exception//将信息反馈给服务端
{
OutputStream sockOut = sock.getOutputStream();
sockOut.write(infoStr.getBytes());
}
public File getClientFileName(InputStream sockIn) throws Exception //获取文件名并创建
{
//获取客户端请求发送的文件名,并判断在D盘创建同名文件的情况
byte[] bufName=new byte[1024];
int lenInfo =0;
lenInfo = sockIn.read(bufName); //获取文件名
String fileName = new String(bufName,0,lenInfo);
File dir = new File("d:\\"); //存到D盘根目录
File[] files=dir.listFiles(); //遍历d盘目录
for(File f:files)
{
if(!f.isDirectory()) //如果遍历到的该文件不是一个目录的话
{
if(f.getName().equals(fileName)) //判断是否是同名文件
{
s.op(f.getName()+"文件已存在,断开该ip连接."+System.getProperty("line.separator"));
writeOutInfo(sock,"服务端已存在同名文件!"); //反馈给客户端的信息
return null;
}
}
}
s.op("将客户端发来的文件( "+fileName+" )存到"+dir.getAbsolutePath());
File file= new File(dir+fileName);
if(file.createNewFile())
{
s.op("成功创建文件("+fileName+" )准备写入数据");
writeOutInfo(sock,"FileSendNow"); //告诉客户端,开始传送数据吧
return file;
}
else
{
return null; //如果由于硬盘满了等原因创建文件失败的话
}
}
}
class s
{
public static void op(Object obj) //打印
{
System.out.println(obj);
}
}
http://xouou.iteye.com/blog/1387875
相关文章推荐
- socket C/C++编程(6)server之accept()函数创建新socket以单独读取缓存区某个client的连接信息(客户端的IP和端口,但是,不包括client端键入的数据)
- 为什么ServerSocket接收不到客户端Socket发送的信息?
- Delphi 实现传送文件 <TServerSocket/TClientSocket>
- (死亡历险)Delphi7 IdTCPClient1,IdTCPServer1客户端向服务端传送大型文件
- navicat连接oracle的错误:ora-12737:instant client light :unsupport server charater set ZHS16GBK解决办法。(oracle服务端字符集,客户端字符集,dmp备份文件字符集,or
- 译文:异步Socket服务器与客户端(An Asynchronous Socket Server and Client) (转)
- ServerSocket和Socket建立通信(客户端发送消息服务器接收输出)
- java使用socket上传文件,实现server端和client端
- Socket TCP Server一个端口可以有多少个长连接?受到什么影响?linux最大文件句柄数量总结
- GCM 发送接收消息 Message Client Server 服务器端,客户端
- [转载]异步Socket服务器与客户端(An Asynchronous Socket Server and Client)
- GCM 发送接收消息 Message Client Server 服务器端,客户端
- 一个linux下socket编程的例子,client连server
- 转:Socket在阻塞模式下的信息收发和文件接收
- C# socket 简单实现server呈现client发送信息
- 如何开发一个SocketServer-Client模型的程序
- 关于socket应用:一个不断监听一个进程的服务器以及发送信息的客户端 TCP的三次握手和四次挥手
- Socket在阻塞模式下的信息收发和文件接收
- Android Push Notification(Android客户端信息推送) (androidpn-server和androidpn-client)
- MFC # socket # C++ # Server端读源文件,发送到Client端,输出按源文件同样的格式