socket client传文件到server,server端接收成功后给客户端反馈一个信息

来源:互联网 发布:数据的离散程度用描述 编辑:程序博客网 时间:2024/05/01 17:43

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

原创粉丝点击