zoukankan      html  css  js  c++  java
  • java Socket(TCP)编程小项目

    package 服务器端相关操作;
    
    import java.io.Serializable;
    
    /*
     * 创建存储需要传输信息的对象,方便客户端向服务器端传送数据
     */
    public class ClientToServerInfo implements Serializable{
        String sign;
        String name;
        String password_OR_path;
        //重写构造函数
        public ClientToServerInfo(String sign,String name,String password_OR_path){
            this.sign=sign;
            this.name=name;
            this.password_OR_path=password_OR_path;
        }
        
        public String getSign() {
            return sign;
        }
        public void setSign(String sign) {
            this.sign = sign;
        }
        public String getName() {
            return name;
        }
        public void setName(String Name) {
            this.name = name;
        }
        public String getPassword_OR_path() {
            return password_OR_path;
        }
        public void setPassword_OR_path(String password_OR_path) {
            this.password_OR_path = password_OR_path;
        }
        @Override
        public String toString() {
            return "客户端说: [sign=" + sign + ", name=" + name + ", password_OR_path=" +password_OR_path + "]";
        }
    
    }
    
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /*
     * 服务器端主程序操作
     */
    public class Server {
    
        public static void main(String[] args) {
            try {
                //1.创建服务器端的ServerSocket,指定伴随的端口号
                ServerSocket serversocket=new ServerSocket(8880);
                System.out.println("****服务器端即将启动,等待客户端*****");// 提示服务器开启
                Socket socket=null;
                while(true){
                    //2.调用accept()方法开始监听,等待客户端连接
                    
                    socket=serversocket.accept();
                    //调用线程
                    ServerThread st=new ServerThread(socket);
                    st.start();
                }
            
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    }
    
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.ObjectInputStream;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.sql.SQLException;
    
    import Server_To_Client_Response.Add_File_Response;
    import Server_To_Client_Response.Add_User_Response;
    import Server_To_Client_Response.Select_User_Response;
    
    public class ServerThread extends Thread {
        //创建与本线程相关的socket
         Socket socket=null;
         ObjectInputStream ois=null;
         //重写构造函数
         public ServerThread(Socket socket){
            this.socket=socket; 
         }
         //线程操作 获取输出流,响应客户端的请求
         public void run(){
            
                try {
                    //3.获取输入流,并读取客户端信息
                    ois=new ObjectInputStream(socket.getInputStream());
                         /*
                          * 读取接收到的对象信息
                          */
                         while( ois.available()!=-1){
                         ClientToServerInfo ctsi =(ClientToServerInfo)ois.readObject();
                         System.out.println(ctsi.toString());//打印客户端传到服务器的数据(对象)
                         /*
                          * 需要客户端传入的对象数据进行分析,根据传入的sign标志值进行相应的操作
                          * sign="1"完成注册会员操作,链接数据库,向数据库中user表添加记录
                          * sign="2"完成会员登录操作,连接数据库,在数据库中user表查询记录
                          * sign="3"完成文件上传操作,连接数据库,向数据库中file表添加记录
                          */
                         //System.out.println(ctsi.sign);
                         if(ctsi.sign.equals("1")){
                             //调用 Add_User_Response类的构造方法对客户端传入的信息进行详细的响应
                             Add_User_Response aur=new Add_User_Response(socket, ctsi.name,ctsi.password_OR_path);
                            //System.out.println("运行完Add_User_Response类");
                            break;
                         }
                         if(ctsi.sign.equals("2")){
                             //调用 Select_User_Response类的构造方法对客户端传入的信息进行详细的响应
                             Select_User_Response sur=new Select_User_Response(socket, ctsi.name,ctsi.password_OR_path);
                             //System.out.println("运行完 Select_User_Response类");
                             break;
                         }
                         if(ctsi.sign.equals("3")){
                            //调用  Add_File_Response类的构造方法对客户端传入的信息进行详细的响应
                             Add_File_Response afr=new Add_File_Response(socket, ctsi.name,ctsi.password_OR_path);
                            // System.out.println("运行完 Add_File_Response类");
                             break;
                         }
                         }
                         
                        //5.关闭资源
                         ois.close();
                        
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            
            }
    
         }
      1 package 客户端相关操作;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.IOException;
      5 import java.io.InputStream;
      6 import java.io.InputStreamReader;
      7 import java.io.ObjectOutputStream;
      8 import java.io.OutputStream;
      9 import java.io.PrintWriter;
     10 import java.net.Socket;
     11 import java.net.UnknownHostException;
     12 import java.util.Scanner;
     13 
     14 import org.eclipse.persistence.oxm.record.OutputStreamRecord;
     15 
     16 import 服务器端相关操作.ClientToServerInfo;
     17 
     18 public class Client {
     19 
     20     public static void main(String[] args) throws UnknownHostException, IOException {
     21         String []data=new String[3];
     22         int sum=0;//用来记录客户端第几次传值到服务器端
     23         /*
     24          * 客户端界面的提示语句
     25          */
     26         ClientTips ctps=new ClientTips();
     27         Scanner sc=new Scanner(System.in);
     28         int n;
     29         
     30         /*
     31          * 客户端实现与服务器端交互
     32          */
     33         
     34         try {
     35         while(true){//使得客户端始终处于程序运行当中
     36             //1.创建客户端socket,指定服务器和端口号
     37             Socket socket=new Socket("localhost", 8880);
     38             OutputStream os=null;
     39             InputStream is=null;
     40             InputStreamReader isr=null;
     41             BufferedReader br=null;
     42             ClientToServerInfo ctsi=null;
     43             ObjectOutputStream oos=null;
     44             while(true){//通过循环让客户端完成注册、登录    和上传信息的客户界面操作
     45                 n=sc.nextInt();
     46                 /*
     47                  * data用于接收tipchoose返回的字符串数组
     48                  * 如果传入的值为1时返回的为三个非空字符串,分别为“1”和用户名和密码
     49                  * 如果传入的值为2是返回的为两个非空字符串,分别是“2”和用户名和密码
     50                  * 如果传入的值为3是返回的两个字符串,分别是“3”和data[0]=null,data[1]=文件路径
     51                  */
     52             data=ctps.tipChoose(n);
     53             if(data[0]!=null&&data[1]!=null){
     54                 //如果界面输入值合理,则跳出一层循环
     55                 break;
     56               }
     57             }
     58             
     59     
     60                 //2.获取输出流,向服务器端发送信息
     61                 os=socket.getOutputStream();//字节输出流
     62                 
     63                 /*
     64                  *这里要判断是不是第一次写文件,若是则写入头部,否则不写入。 
     65                  */
     66                 //if(sum==0){
     67                    oos=new ObjectOutputStream(os);
     68                 //}
     69                 /*else{
     70                     System.out.println(sum);
     71                    oos=new MyObjectOutputStream(os);
     72                 }*/
     73                 
     74                 
     75                 //将需要传送的信息封装成对象
     76                 ctsi=new ClientToServerInfo(data[0],data[1],data[2]);
     77                 
     78                 oos.writeObject(ctsi);
     79                 oos.writeObject(null);//objectoutputstream写入结束的标志
     80                 oos.flush();
     81                 sum++;
     82                 //socket.shutdownOutput();//关闭输出流
     83 
     84                 //3.读取服务器端发送的信息
     85                 is=socket.getInputStream();
     86                 isr=new InputStreamReader(is);
     87                 br=new BufferedReader(isr);
     88                  String info=null;
     89                 if((info=br.readLine())!=null){
     90                     System.out.println("我是客户端,服务器说:"+info);
     91                 }
     92                 //用来区分不同次的客户端发送和服务器响应的命令
     93                 System.out.println("**************************");
     94                 //关闭输入输出流(关闭资源)
     95                 br.close();
     96                 isr.close();
     97                 is.close();
     98                 oos.close();
     99                 os.close();
    100                 socket.close();
    101                         
    102         }
    103         } catch (IOException e) {
    104             // TODO Auto-generated catch block
    105             e.printStackTrace();
    106         }
    107     }        
    108 }    
    109 
    110 
    111 import java.util.Scanner;
    112 
    113 public class ClientTips {
    114     static boolean flag=false;
    115     static String a;
    116     public ClientTips(){
    117     //打印客户端界面
    118             System.out.println("*********************************");
    119             System.out.println("注册信息:1");
    120             System.out.println("登陆账号:2");
    121             System.out.println("上传文件(只有在登陆之后才能传文件!):3");
    122             System.out.println("*********************************");
    123     }
    124     public String[] tipChoose(int n){
    125     String[] userinfo=new String[3];
    126     String b,c,e;
    127     Scanner sc=new Scanner(System.in);
    128     
    129     /*
    130      * 注册时的提示操作
    131      */
    132     if(n==1){
    133         System.out.print("请输入要注册的账号名:");
    134         a=sc.nextLine();
    135         System.out.print("请输入密码:");
    136         b=sc.nextLine();
    137         System.out.print("请确认密码:");
    138         c=sc.nextLine();
    139         if(!c.equals(b)){//这里不能用c!=b判断,c!=b不仅对比了字符串,还对比了存储地址
    140             System.out.println("密码不一致!注册失败,需要重新注册请输入:1");
    141             //如果注册失败,userinfo返回的为空数组
    142             userinfo[0]=null;
    143             userinfo[1]=null;
    144             userinfo[2]=null;
    145         }
    146         else{
    147             userinfo[0]="1";
    148             userinfo[1]=a;
    149             userinfo[2]=b;
    150         }
    151     }
    152     /*
    153      * 登陆时提示信息操作
    154      */
    155     if(n==2){
    156         System.out.print("请输入要登陆的账号名:");
    157         a=sc.nextLine();
    158         System.out.print("请输入密码:");
    159         b=sc.nextLine();
    160         userinfo[0]="2";
    161         userinfo[1]=a;
    162         userinfo[2]=b;
    163         flag=true;
    164         
    165     }
    166     
    167     /*
    168      * 传送文件相关文件
    169      */
    170     if(n==3){
    171         if(flag!=true){
    172             System.out.println("请先登录账号!请输入2");
    173             //如果没有登陆操作,输入3时先返回空数组
    174             userinfo[0]=null;
    175             userinfo[1]=null;
    176             userinfo[2]=null;
    177         }
    178         else{
    179             System.out.println("请输入文件的路径:");
    180             e=sc.nextLine();
    181             userinfo[0]="3";
    182             userinfo[1]=a;
    183             userinfo[2]=e;
    184         }
    185     }
    186     return userinfo;    
    187     }
    188 }
    189 
    190 
    191 import java.io.Serializable;
    192 
    193 /*
    194  * 创建存储需要传输信息的对象,方便客户端向服务器端传送数据
    195  */
    196 public class ClientToServerInfo implements Serializable{
    197     String sign;
    198     String name;
    199     String password_OR_path;
    200     //重写构造函数
    201     public ClientToServerInfo(String sign,String name,String password_OR_path){
    202         this.sign=sign;
    203         this.name=name;
    204         this.password_OR_path=password_OR_path;
    205     }
    206     
    207     public String getSign() {
    208         return sign;
    209     }
    210     public void setSign(String sign) {
    211         this.sign = sign;
    212     }
    213     public String getName() {
    214         return name;
    215     }
    216     public void setName(String Name) {
    217         this.name = name;
    218     }
    219     public String getPassword_OR_path() {
    220         return password_OR_path;
    221     }
    222     public void setPassword_OR_path(String password_OR_path) {
    223         this.password_OR_path = password_OR_path;
    224     }
    225     @Override
    226     public String toString() {
    227         return "客户端说: [sign=" + sign + ", name=" + name + ", password_OR_path=" +password_OR_path + "]";
    228     }
    229 
    230 }
    231 
    232 
    233 import java.io.IOException;
    234 import java.io.ObjectOutputStream;
    235 import java.io.OutputStream;
    236 /*
    237  * 在一个文件都有一个文件的头部和文件体。由于对多次使用FileOutputStream(文件名,true)
    238  * 构建的ObjectOutputStream对象向同一个文件写数据,在每次些数据的时候他都会向这个文件末
    239  * 尾先写入header在写入你要写的对象数据,在读取的时候遇到这个在文件体中的header就会报错。
    240  * 导致读出时,出现streamcorrput异常。(解决办法:所以这里要判断是不是第一次写文件,若是
    241  * 则写入头部,否则不写入)
    242  */
    243 public class MyObjectOutputStream extends ObjectOutputStream {
    244 
    245     protected MyObjectOutputStream() throws IOException, SecurityException {
    246         super();
    247     }
    248     
    249     
    250      public MyObjectOutputStream(OutputStream out) throws IOException {
    251            super(out);
    252           } 
    253           @Override 
    254 
    255     protected void writeStreamHeader() throws IOException { 
    256              return;
    257           }
    258          } 
      1 package Database;
      2 
      3 import java.sql.Connection;
      4 import java.sql.DriverManager;
      5 import java.sql.SQLException;
      6 
      7 public class DBUtil {
      8 
      9     private static final String URL="jdbc:mysql://127.0.0.1:3306/imooc?useUnicode=true&characterEncoding=utf-8";
     10     private static final String USER="root";
     11     private static final String PASSWORD="tiger";
     12     
     13     private static Connection conn=null;
     14     
     15     static {
     16         try {
     17             //1.加载驱动程序
     18             Class.forName("com.mysql.jdbc.Driver");
     19             //2.获得数据库的连接
     20             conn=DriverManager.getConnection(URL, USER, PASSWORD);
     21         } catch (ClassNotFoundException e) {
     22             e.printStackTrace();
     23         } catch (SQLException e) {
     24             e.printStackTrace();
     25         }
     26     }
     27     //将获得的数据库与java的链接返回(返回的类型为Connection)
     28     public static Connection getConnection(){
     29         return conn;
     30     }
     31 
     32 }
     33 
     34 /*
     35  * 服务器端链接数据库,并向数据库表user添加数据
     36  * 添加成功返回true,否则返回false
     37  */
     38 import java.sql.Connection;
     39 import java.sql.PreparedStatement;
     40 import java.sql.SQLException;
     41 
     42 public class Database_Add_User {
     43     boolean flag=false;
     44     //
     45     public boolean Database_Add_User_run(String name,String password_OR_path) throws SQLException{
     46         //获取mysql链接
     47         System.out.println("开始运行Database_Add_User类");
     48         Connection conn=DBUtil.getConnection();
     49         String sql=""+"insert into user"+"(user_name,user_password)"
     50                     +"values("+"?,?)";
     51         //加载sql语句到执行程序中(并不进行执行)
     52         PreparedStatement ptmt=conn.prepareStatement(sql);
     53         ptmt.setString(1, name);
     54         ptmt.setString(2, password_OR_path);        
     55         flag=ptmt.execute();
     56         return flag;
     57     }
     58 }
     59 
     60 /*
     61  * 用于用户登录时,将账号和密码传递到数据库,
     62  * 若登录名不存在file表中(即未注册)返回2
     63  * 若登录名存在file表中,密码输入正确返回1
     64  * 若登录名存在file表中,密码输入错误返回3
     65  */
     66 import java.sql.Connection;
     67 import java.sql.PreparedStatement;
     68 import java.sql.ResultSet;
     69 import java.sql.SQLException;
     70 
     71 public class Database_Select_User {
     72     
     73     
     74     public int Database_Select_User_run(String name,String password_OR_path) throws SQLException{
     75         //获取mysql链接
     76         Connection conn=DBUtil.getConnection();
     77         String sql1=""+"select * from user where user_name like ?";
     78         PreparedStatement ptmt=conn.prepareStatement(sql1.toString());
     79         ptmt.setString(1, "%"+name+"%");
     80         ResultSet rs=ptmt.executeQuery();
     81         while(rs.next()){
     82             //判断密码是否正确,正确返回1
     83             if(rs.getString("user_password").equals(password_OR_path)){
     84                 return 1;
     85             }
     86             //判断密码错误返回2
     87             else
     88                 return 3;
     89         }
     90         //用户名不存在返回2
     91         return 2;
     92         
     93     }
     94 
     95 }
     96 
     97 /*
     98  * 服务器端链接数据库,并向数据库表file添加数据
     99  * 添加成功返回false,否则返回true
    100  */
    101 
    102 import java.io.File;
    103 import java.io.FileInputStream;
    104 import java.io.FileNotFoundException;
    105 import java.io.InputStream;
    106 import java.sql.Connection;
    107 import java.sql.PreparedStatement;
    108 import java.sql.SQLException;
    109 
    110 public class Database_Add_File {
    111     boolean flag=false;
    112     //
    113     public boolean Database_Add_File_run(String name,String password_OR_path) throws SQLException, FileNotFoundException{
    114         //获取mysql链接
    115         File files = new File(password_OR_path);
    116         Connection conn=DBUtil.getConnection();
    117         String sql=""+"insert into file"+"(user_name,path)"
    118                     +"values("+"?,?)";
    119         //加载sql语句到执行程序中(并不进行执行)
    120         PreparedStatement ptmt=conn.prepareStatement(sql);
    121         ptmt.setString(1, name);
    122         //ptmt.setString(2, password_OR_path);
    123         FileInputStream fis = new FileInputStream(files);
    124         ptmt.setBinaryStream(2, (InputStream) fis, (int) (files.length()));
    125         flag=ptmt.execute();
    126         return flag;
    127         }
    128     }
      1 package Server_To_Client_Response;
      2 /*
      3  * 判断客户端传入到服务器端的注册会员数据,提交到数据库中,
      4  * 是否在数据库中添加成功,并完成对客户端的响应,成功返回注册成功,
      5  * 反之提示其重新注册
      6  */
      7 import java.io.IOException;
      8 import java.io.OutputStream;
      9 import java.io.PrintWriter;
     10 import java.net.Socket;
     11 import java.sql.SQLException;
     12 
     13 import Database.Database_Add_User;
     14 
     15 public class Add_User_Response {
     16     Socket socket=null;
     17     boolean flag;
     18     public Add_User_Response(Socket socket,String name,
     19             String password_OR_path ) throws SQLException{
     20         
     21         try {
     22             System.out.println("运行Add_User_Response类");
     23             //将已创建的socket对象加载进来
     24             
     25             this.socket=socket;
     26             OutputStream os=socket.getOutputStream();
     27             PrintWriter pw=new PrintWriter(os);
     28             /*
     29              * 创建和数据库的链接,完成向user表格中添加记录操作
     30              * 添加成功返回false,否则返回true
     31              */
     32             Database_Add_User dau=new Database_Add_User();
     33             flag=dau.Database_Add_User_run(name, password_OR_path);
     34             //System.out.println("运行完Database_Add_User类");
     35             /*
     36              * 对插入数据后的返回值进行分析,并对客户端进行响应
     37              */
     38             if(!flag){
     39                 //获取输出流,响应客户端的请求
     40                     pw.write("您已经成功注册!");
     41                     pw.flush();
     42                 
     43             }
     44             else{
     45                 pw.write("注册失败!");
     46                 pw.flush();
     47             
     48             }
     49             //关闭输入输出流(关闭资源)
     50             pw.close();
     51             os.close();
     52             } catch (IOException e) {
     53             // TODO Auto-generated catch block
     54             e.printStackTrace();
     55         }finally {
     56             
     57             try {
     58                 
     59                 socket.close();
     60             } catch (IOException e) {
     61                 // TODO Auto-generated catch block
     62                 e.printStackTrace();
     63             }
     64         }
     65         
     66         }
     67     }
     68 
     69 
     70 /*
     71  * 判断客户端传入到服务器端的上传文件数据,提交到数据库中,
     72  * 是否在数据库中添加成功,并完成对客户端的响应,成功返回上传成功,
     73  * 反之提示其重新上传
     74  */
     75 import java.io.IOException;
     76 import java.io.OutputStream;
     77 import java.io.PrintWriter;
     78 import java.net.Socket;
     79 import java.sql.SQLException;
     80 
     81 import Database.Database_Add_File;
     82 
     83 public class Add_File_Response {
     84     OutputStream os=null;
     85     PrintWriter pw=null;
     86     Socket socket=null;
     87     boolean flag;
     88     public Add_File_Response(Socket socket,String name,
     89             String password_OR_path ) throws SQLException, IOException{
     90         //将已创建的socket对象加载进来
     91         this.socket=socket;
     92         os=socket.getOutputStream();
     93         pw=new PrintWriter(os);
     94         /*
     95          * 创建和数据库的链接,完成向file表格中添加记录操作
     96          *  添加成功返回false,否则返回true
     97          */
     98         
     99         Database_Add_File dau=new Database_Add_File();
    100         flag=dau.Database_Add_File_run(name, password_OR_path);
    101         
    102         /*
    103          * 对插入数据后的返回值进行分析,并对客户端进行响应
    104          */
    105         if(!flag){
    106             //获取输出流,响应客户端的请求
    107                 pw.write("文件上传成功!");
    108                 pw.flush();
    109         }
    110         else{
    111             pw.write("文件上传失败!请重新上传!");
    112             pw.flush();
    113         }
    114         //关闭输入输出流(关闭资源)
    115         pw.close();
    116         os.close();
    117     }
    118 }
    119 
    120 
    121 /*
    122  * 判断客户端传入到服务器端的会员数据,提交到数据库中,
    123  * 在数据库中查找,是否注册,密码是否正确,若账号名和密码都正确,登陆成功
    124  * 并完成对客户端的响应。
    125  */
    126 import java.io.IOException;
    127 import java.io.OutputStream;
    128 import java.io.PrintWriter;
    129 import java.net.Socket;
    130 import java.sql.SQLException;
    131 
    132 import Database.Database_Select_User;
    133 
    134 public class Select_User_Response {
    135     //输出流的初始化,为服务器对客户端的响应做准备
    136     OutputStream os=null;
    137     PrintWriter pw=null;
    138     Socket socket=null;
    139     int flag;
    140     public Select_User_Response(Socket socket,String name,
    141             String password_OR_path) throws IOException, SQLException{
    142         this.socket=socket;
    143         os=socket.getOutputStream();
    144         pw=new PrintWriter(os);
    145         /*
    146          * 创建和数据库的链接,完成对user表格的查询操作(完成登陆)
    147          * 若登录名不存在file表中(即未注册)返回2
    148          * 若登录名存在file表中,密码输入正确返回1
    149          * 若登录名存在file表中,密码输入错误返回3
    150          */
    151         Database_Select_User dsu=new Database_Select_User();
    152         flag=dsu.Database_Select_User_run(name,password_OR_path);
    153         
    154         /*
    155          * 对查找返回的数据进行分析,并对客户端进行响应
    156          */
    157         if(flag==1){
    158                pw.write("欢迎您,你已经完成登陆!请输入3");
    159                pw.flush();
    160         }
    161         else if(flag==2){
    162              pw.write("您还没进行注册,请先注册!");
    163                pw.flush();
    164         }
    165         else{
    166              pw.write("密码错误!请重新登陆!请输入2");
    167                pw.flush();             
    168         }
    169         //关闭输出输入流(关闭资源)
    170         pw.close();
    171         os.close();
    172     }
    173 }
  • 相关阅读:
    监控注册表和文件夹改动
    Windows中根据GetLastError的错误代码,取得文字描述
    VBA 读取文件/写入文件
    (转)ansi,gb2312,gbk,gb18030,unicode,utf8,unicode big endian编码的区别及什么是BOM
    VBA 打开文件对话框
    修改GitHub记录中的invalidemailaddress
    使用DWM实现Aero Glass效果
    RAII(C++必知必会 条款40)
    C函数包装ASM代码时,指针无法传值的问题
    msysgit color.ui auto is invalid msysgit无法开启彩色显示
  • 原文地址:https://www.cnblogs.com/xiaotiaosi/p/6389418.html
Copyright © 2011-2022 走看看