package com.gx.obe.server.im.serverthread; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.BindException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import org.slf4j.Logger; import com.gx.obe.server.im.ChatConstants; import com.gx.obe.server.im.IMConstants; import com.gx.obe.server.im.SendFileParam; public class SendFileThread implements ServerFileThread{ private String fileName; private BufferedInputStream bis; private FileInputStream fis ; private BufferedOutputStream bos; private ServerSocket sst; private Socket cs; private File file; private boolean isWait = false; private InetAddress clientIp; private static Integer lixianPort = 1980;//离线文件接收起始端口,一开始就自动+1 private String serverIp; private String fileId; private long threadId = 0; private Logger LOG = org.slf4j.LoggerFactory.getLogger(SendFileThread.class); private ServerSendFileListener listener; private Thread thread = null; private SendFileParam params; //当离线文件发到服务器后,接收者在线的情况下,服务器立即转给接收者(fuid赋给了tuid) public SendFileThread(SendFileParam params, InetAddress ip, ServerSendFileListener listener){ this.listener = listener; this.params = params; this.clientIp = ip; this.fileId = params.getFileId(); this.serverIp = params.getSendIp(); this.fileName = params.getFileName(); // this.tuid = params.getSendId(); // this.fuid = params.getReceiveId(); file = new File(System.getProperty("user.dir") + ChatConstants.UPFILE + fileName); } /** * @Description: 启动发送文件线程 * @author guoyr */ public void start(){ thread = new Thread(this); this.threadId = thread.getId(); thread.setName("发送文件线程" + threadId); thread.start(); } public void deleteFile(){ if ( file != null && file.exists() ){ file.delete(); } } public void init(){ try{ while(null != thread){ try { sst = new ServerSocket(lixianPort); break; } catch (BindException ex) { lixianPort ++; continue; } catch (IOException ex) { return; } } SendFileParam newParams = new SendFileParam(); newParams.setOrder(IMConstants.SEND_OFFLINE_FILE_REQUEST); newParams.setSendId(params.getSendId()); newParams.setReceiveId(params.getReceiveId()); newParams.setFileName(fileName); newParams.setFileSize(file.length()); newParams.setSendPort(lixianPort); newParams.setSendIp(serverIp); newParams.setFileId(fileId); newParams.setThreadId(this.getThreadId()); // String str = OperatorUtil.SEND_OFFLINE_FILE_REQUEST + FG + tuid + FG + fuid + FG + file.length() // + FG + fileName + FG + lixianPort + FG + serverIp + FG + this.getId() + FG + fileId; // 先发送离线文件请求,让接收着准备接收离线文件 // sendLixianFileTongZhi(str); listener.sendOfflineFileRequest(newParams.getReceiveId(), newParams.getOrderStr()); lixianPort ++; if ( lixianPort > 7999 ) lixianPort = 1981; sst.setReceiveBufferSize(ChatConstants.MAX_LENGTH); cs = sst.accept(); // 同意接收离线文件后开始发送 isWait = true; }catch(Exception e){ } } public void run() { try{ if (!file.exists() || clientIp == null ) return; init(); while(null != thread){ if ( isWait ){ fis = new FileInputStream(file); bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(cs.getOutputStream()); byte[] bs = new byte[ChatConstants.MAX_LENGTH]; int len = bis.read(bs); while( len != -1 ){ bos.write(bs, 0, len); bos.flush(); len = bis.read(bs); } stop(); isWait = false; break; } Thread.sleep(500); } }catch(Exception e){ LOG.error(e.getMessage()); }finally { stop(); } } /** * @Description: 停止发送文件线程 * @author guoyr */ public void stop(){ listener.removeServerFileThread(this); thread = null; if ( bos != null ){ try { bos.close(); } catch (IOException e) { } bos = null; } if ( bis != null ){ try { bis.close(); } catch (IOException e) { } bis = null; } if ( fis != null ){ try { fis.close(); } catch (IOException e) { } fis = null; } if ( cs != null ){ try { cs.close(); } catch (IOException e) { } cs = null; } if ( sst != null ){ try { sst.close(); } catch (IOException e) { } sst = null; } if(null != file && file.exists()){ file.delete(); } } public long getThreadId() { return threadId; } /**
* @Description: 监听是否发送完成 * @Description: * @author guoyr **/ public interface ServerSendFileListener{ public void removeServerFileThread(ServerFileThread serverFileThread); public void sendOfflineFileRequest(String receiveId, String order); } public boolean isStop() { return null == thread; } }