Socket 聊天室收发文件

TcpServer

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.Provider;
import java.util.*;
public class TcpServer {
    //创建 一个客服端的集合 之后会遍历
    public static  List<Client_channel> list = new ArrayList<Client_channel>();
    public static List<File_server> list2 = new ArrayList<File_server>();
         //定义两个端口
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8888);
        ServerSocket  serverSocket1 = new ServerSocket(8889);
         //用于发送文件的端口
        while(true){
              Socket socket = serverSocket.accept();
              System.out.println("现在有一个线程进来了!!");
              Socket socket1= serverSocket1.accept();
              Client_channel client_channel = new Client_channel(socket);
              list.add(client_channel);
              File_server file_server = new File_server(socket1);
              list2.add(file_server);
               new Thread(client_channel).start();
               new Thread(file_server).start();
        }
    }
}




File_serve

/*
用于服务器进行收发文件线程的操作
 */

import java.io.*;
import java.net.Socket;
import java.security.AccessControlException;
import java.util.List;
public class File_server  implements  Runnable {
    public  DataInputStream Input;
    public DataOutputStream output;
    private boolean flag=true;
    private BufferedReader bf;
    private PrintWriter pw;
    private  int number;
    private Socket socket;
    public  File_server(Socket socket){
        // init
        this.socket= socket;
        try {
            Input = new DataInputStream(this.socket.getInputStream());
            output = new DataOutputStream(this.socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
          TcpServer.list2.remove(this);
        }
        //传入对象
    }
    @Override
    public void run() {
        try{
            while(true){
                //  需要接收文件的大小
           String  textName = Input.readUTF();
           long textLength = Input.readLong();
     for( int i =0;i<TcpServer.list2.size();i++){
         if(TcpServer.list2.get(i).equals(this)){
             continue;
         }
         else {
               TcpServer.list2.get(i).output.writeUTF(textName);
             TcpServer.list2.get(i).output.flush();
             TcpServer.list2.get(i).output.writeLong(textLength);
             TcpServer.list2.get(i).output.flush();
         }
     }
     // 发送内容
                int length = -1;
          long curLength =0;
          byte [] buff = new byte [1024];
          while((length = Input.read(buff))>0){
              curLength+=length;
              for( int i =0;i<TcpServer.list2.size();i++){
                  if(TcpServer.list2.get(i).equals(this)){
                      continue;
                  }
                  else {
                      //发送内容
                      TcpServer.list2.get(i).output.write(buff,0,length);
                      TcpServer.list2.get(i).output.flush();
                  }
              }
              if(curLength==textLength){
                  break;
              }
          }
            }
        }
        catch (Exception e){
  TcpServer.list2.remove(this);
        }
    }
}

Client_sta

public class Client_sta   {
     public  static  int number=0;
    public static void main(String[] args) {
        for( int i =0;i<3;i++){
        new  client(i);
        }
    }

}




import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
public class client  extends JFrame  implements   ActionListener,Runnable
{
    public   int number;
     // 利用number 存储文件名
    private  JTextArea jTextArea;
    private  JPanel jPanel;
    private  JButton jb;
    public  Socket file_socket;
    private  JButton  jb_file;
    private JScrollPane jScrollPane;
    private JTextField jTextField;
    private  DataOutputStream dos;
    private  Send send;
    public  Socket socket;
    private  Filesend filesend;
    private  Thread thread;
    public  client ( int number){
        super("my_chat");
        //通信相关
        this.number=number;
        try {
            this.socket= new Socket("127.0.0.1",8888);
            this.file_socket= new Socket("127.0.0.1",8889);
            this.filesend = new Filesend(this);
             //申请不同的端口号
              this.dos= new DataOutputStream(this.socket.getOutputStream());
           this.send= new Send(this.socket);
            //this.receive= new Receive(this.socket);
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this,"连接不到服务器");
        }
        this.jTextArea= new JTextArea();
        this.jTextField= new JTextField(10);
        this.jScrollPane= new JScrollPane(this.jTextArea);
        this.jb= new JButton("send");
       this.jb_file= new JButton("send_file");
       this.jb_file.addActionListener(this); //this 处理
       //发送文件按钮
        this.jPanel= new JPanel();
        //添加组件
        this.getContentPane().setLayout( new BorderLayout());
        this.getContentPane().add(this.jScrollPane,BorderLayout.CENTER);
        this.getContentPane().add(this.jPanel,BorderLayout.SOUTH);
        this.jPanel.add(this.jTextField);
        this.jPanel.add(this.jb);  this.jPanel.add(this.jb_file);
        this.jb.addActionListener(this); //由this对象处理
        //位置
        this.setLocationRelativeTo(null);
        this.setBounds(200,400, 400,200);
        this.setResizable(false);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.setVisible(true);
        new Thread(this).start();
        new Thread(this.filesend).start();
    }
// 对于这个问题而言 只要点击按钮就是发送数据
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if(actionEvent.getSource().equals(this.jb)) {
            String str = this.jTextField.getText();
            System.out.println("现在发送 的是"+str);
            if (str == "") {
                JOptionPane.showMessageDialog(this, "不能为空!!");
            } else {
                Send.str=str;
                new Thread(this.send).start();
                this.jTextArea.append("\n" + "me say :" + str);
                System.out.println("正在发送数据!!");
                //点击发送之后发送线程启动
            }
        }
        // 函数的调用  发送文件
        if(actionEvent.getSource().equals(this.jb_file)){
           // 提示查看文件的目录 ,在控制台输出提示信息 。
          System.out.println("文件成功传输! ,在文件中查看!");
          String str = this.jTextField.getText();
          this.filesend.send_file(str);
          //  做一个线程跑接受文件 这个线程的功能就是发送文件  ,接受文件
        }
    }
    @Override
    public void run() {
        System.out.println("客服端正在接受数据!!!");
        DataInputStream inputStream;
        BufferedReader bf;
        try {
            inputStream = new DataInputStream(socket.getInputStream());
            BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream));
          //
            String s=null;
            while((s=buffer.readLine())!=null){ //应该是会阻塞自己的

                 System.out.println("收到了"+s);
                this.jTextArea.append("\n"+s);
            }
        } catch (IOException e) {
        }
    }
}




Filesend

import javax.swing.*;
import java.io.*;
import java.net.Socket;
/*
用于客服端发送接收文件
 */
public class Filesend implements Runnable {
   // 接受、发送文件
    private File file;
   private  DataOutputStream fileWriter ;
   private DataInputStream fileReader;
    private DataInputStream file_in;
    private  DataOutputStream file_out;
    private  String filename;
    private  client  my_client;
    private Socket socket;
    private File userFile;
    public Filesend(client c){
        this.my_client=c;
        try {
           this.socket=this.my_client.file_socket;
            this.file_in= new DataInputStream(socket.getInputStream());
             this.file_out= new DataOutputStream(socket.getOutputStream());
           this.userFile= new File("D:\\idea socket\\"+this.my_client.number);
        } catch (FileNotFoundException e) {
            JOptionPane.showMessageDialog(this.my_client,"请检查文件是不是存在!!");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //发送文件只是发送一次即可
    public void send_file(String str){
        // 如果是重新进行套接字的连接的话 ,发送文件
     this.file = new File(str);
     try{
         this.fileReader= new DataInputStream(new FileInputStream(file));
         file_out.writeUTF(file.getName());
         file_out.flush();
         file_out.writeLong(file.length());
         file_out.flush();
         int length=-1;
         byte [] buff = new byte[1024];
         while((length=fileReader.read(buff))>0){
             file_out.write(buff,0,length);
             file_out.flush();
         }
     }catch (IOException e){
         e.printStackTrace();
     }
    }
    @Override
    public void run(){
        //客服端如何进行接受呢 ? 这是个问题
         // 重新设置套接字吗  服务器怎么区分数据
        try {
            while(true) {
                String textName = file_in.readUTF(); //文件名称
                long Length = file_in.readLong(); //文件长度
                int result = JOptionPane.showConfirmDialog(this.my_client, "是不是接收文件?", "提示", JOptionPane.YES_NO_CANCEL_OPTION);
                int len = -1;
                byte[] buff = new byte[1024];
                long curLength = 0;
                if (result == 0) {
                    // 接收文件
               if(!userFile.exists()){
                   userFile.mkdir(); //不存在的话创建文件目录
               }
               this.file= new File("D:\\idea socket\\"+this.my_client.number+"\\"+textName);
               System.out.println(this.my_client.number+"文件号码");
               // 接收文件
                    fileWriter = new DataOutputStream(new FileOutputStream(file));
                    //文件输出
                    while((len=file_in.read(buff))>0){
                        fileWriter.write(buff,0,len);  //写入本地
                        fileWriter.flush();
                        curLength+=len;
                        if(curLength==Length){
                            break;
                            // 直接结束
                        }
                    }
                }
                //不接受文件
                else {
                    while ((len=file_in.read(buff))>0){
                        curLength +=len;
                        if(curLength== Length){
                            break;
                        }
                    }
                }
                fileWriter.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Send

import java.io.*;
import java.net.Socket;
/*
发送线程 因为不会只接一次
 */
public class Send  implements  Runnable  {
    public  static  String str;
    public BufferedReader bf;
   public DataOutputStream  dos ;
   private  PrintWriter pw;
   private boolean flag = true;

    public Send(Socket socket){
        try {
            this.dos= new DataOutputStream(socket.getOutputStream());
          this.pw= new PrintWriter(this.dos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public String  my_send(String str){
        String  a= null;
        try {
            //this.dos.writeUTF(str);
            pw.println(str);
            pw.flush();
            //this.dos.flush();
        } catch (Exception e) {
            this.flag=false;
            try {
                this.dos.close();
                //清空缓冲区
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return  a ;
    }
    //收发进程
    @Override
    public void run() {
        //一直在发送 直到this.flag
        System.out.println("客服端正发送"+str);
       this.my_send(Send.str);
       //
    }
    public void close(){

        try{
            this.dos.close();

        }catch (Exception e){
            e.printStackTrace();
        }

    }

}

Client_channel

/*
1.输入流
2.输出流
3.发送数据
4.接收数据
 */
import javax.swing.*;
import java.io.*;
import java.net.Socket;
import java.util.List;
public class Client_channel implements  Runnable {
private DataInputStream dataInputStream;
private DataOutputStream dataOutputStream;
private boolean flag=true;
private BufferedReader bf;
private  PrintWriter pw;
private  int number;
private  Socket socket;
// 构造方法
public Client_channel(Socket socket) {
try{
    number=0;
    this.socket=socket;
    dataInputStream= new DataInputStream(socket.getInputStream());
    dataOutputStream = new DataOutputStream(socket.getOutputStream());
    this.bf= new BufferedReader(new InputStreamReader(dataInputStream));
    this.pw= new PrintWriter(this.dataOutputStream);
    //输入流
}
catch (IOException e){
    this.flag= false;
    try {
        this.dataOutputStream.close();
        this.dataInputStream.close();
    } catch (IOException ex) {
        System.out.println("create 中出错!!");
    }
      }
}
public int getPort(){
    return this.socket.getPort();

}
/*
//receive 数据
    private  String receive()  {
    String str="";
        try {
            str= dataInputStream.readUTF();
            System.out.println("我收到了"+str);
        } catch (IOException e) {
            this.flag= false;
           // 关闭dataInputStream
            try {
                this.dataInputStream.close();
            }
            catch (IOException ex) {
                ex.printStackTrace();
            }
                TcpServer.list.remove(this);
            // 关闭dataInputStream
               }
        return str;
    }
*/

//  send
    private  void send( String str){
    if(str!=""&&str.length()!=0){
        try {
             this.pw.println(str);
             this.pw.flush();
            System.out.println("now the function send 发送"+str);
       //将缓冲区中 的东西强制送出去 防止数据收不到的情况。
        } catch (Exception e) {
            this.flag=false;
            //e.printStackTrace();
        }
    }
    }
    // 给别的进程发送数据
    private  void send_other(String str) {

        System.out.println("  send_other :现在是转发给别的线程" + str);
        List<Client_channel> list = TcpServer.list;
        //
        synchronized ( list) {
            for (int i = 0; i < list.size(); i++) {

              System.out.println("Port is :"+list.get(i).getPort());
                if (list.get(i).equals(this)) {
                    continue;
                }
                list.get(i).send(str);

            }
        }
}
    @Override
    public void run() {
        while (true) {
            try {
           String  s= bf.readLine();
           if(s!=null)
                //线程会阻塞
           {
               this.send_other(s);
           }
                // 一直监听线程发送的内容
            } catch (Exception e) {
                System.out.println("客服端断开连接!!");
                break;
            }
        }
    }
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值