TCP练习

基于TCP协议(面向连接,安全可靠)

步骤:
服务器端:
创建ServeSocket(int port)对象 ///指定端口
在Socket上监听客户端的连接请求
阻塞,等待连接建立
接收并处理请求信息
将处理结果返回客户端
关闭流和Socket对象

客户端:
创建Socket(String host,int port)对象 ///指定服务器位置与端口
向服务器发送连接请求
向服务器发送服务请求
接收服务结果
关闭流和Socket对象

模拟登陆系统底层原理:
服务器端:

public class LoginServer {
    public static void main(String[] args) throws IOException {
        System.out.println("-----Server-----");
        ServerSocket server=new ServerSocket(8888);//创建ServerSocket对象
        Socket client1=server.accept();//在Socket上监听客户端
        System.out.println("一个客户端建立连接");

        DataInputStream dis=new DataInputStream(client1.getInputStream() );
        String data=dis.readUTF();//使用DataInputStream数据输入流得到客户端发送的用户名密码数据
        String []dataArray=data.split("&");
        System.out.println("你的用户名为"+dataArray[0]);
        System.out.println("你的密码为"+dataArray[1]);//将得到的字符串以"&"为界限分割

        //分析数据并且双向输出,返回结果给客户端

        DataOutputStream dos=new DataOutputStream(client1.getOutputStream());
        if(dataArray[0].equals("xiaojiehang")&&dataArray[1].equals("xjh")){
            dos.writeUTF("登陆成功");
        }else{dos.writeUTF("账号密码不匹配");}
        dos.flush();
        dos.close();


        dis.close();
        client1.close();
        //server.close(); //服务器一般不关闭,除了进行维护
    }

}

客户端:

public class LoginClient {

       public static void main(String[] args) throws IOException {
        System.out.println("-----Client-----");
        Scanner scanner=new Scanner(System.in);
   // BufferedReader br=new BufferedReader(new InputStreamReader(System.in));得到键盘输入的其他方式
        System.out.println("输入用户名:");
        String name=scanner.nextLine();
        System.out.println("输入密码:");
        String password=scanner.nextLine();//得到输入的数据

        Socket client=new Socket("localhost",8888);//建立连接,连接服务器的地址与端口
        DataOutputStream dos=new DataOutputStream( client.getOutputStream() );//尽量选用Data流,如果数据是Java的基本数据类型
        dos.writeUTF(name+"&"+password);
        dos.flush();

        //得到服务器的返回值,双向传递
        DataInputStream dis=new DataInputStream( client.getInputStream() );//数据输入流为client插座的输入流
        String result=dis.readUTF();
        System.out.println(result);


        dos.close();//关闭资源
        dis.close();
        client.close();

    }
}

在这里插入图片描述
在这里插入图片描述

改造成多线程(多个客户端)

将服务器端改造成多线程:

Socket client1多次监听客户端的连接请求

public class LoginServer {
    public static void main(String[] args) throws IOException {
        System.out.println("-----Server-----");
        ServerSocket server=new ServerSocket(8888);//创建ServerSocket对象
        boolean isrunning=true;
      while(isrunning) {//是服务器一直运行不关闭,每次监听为一次线程
          Socket client1 = server.accept();//在Socket上监听
          System.out.println("一个客户端建立连接");
          new Thread(new channel(client1)).start();
      }
      server.close();
    }
  static   class channel implements Runnable{
     private DataInputStream dis;
      Socket client1;
      DataOutputStream dos;
      public channel(Socket client1) throws IOException {
          this.client1=client1;
          dis=new DataInputStream(client1.getInputStream() );
          dos=new DataOutputStream(client1.getOutputStream());
      }
      public String receivedata()  {//接收数据
          String data=" ";
          try {
              data = dis.readUTF();//得到用户名密码数据
          } catch (IOException e) {
              e.printStackTrace();
          }
          return data;
      }
      public void senddata(String s)  {//发送数据
          try {
              dos.writeUTF(s);
              dos.flush();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }

      public void release(){//释放资源,目的是使run方法更简洁
          try {
              if(dos!=null){
              dos.close();}
              if(dis!=null){
                  dis.close();}
          } catch (IOException e) {
              e.printStackTrace();
          }
          if(client1!=null){
              try {
                  client1.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }

      }



      @Override
      public void run() {
          String []dataArray=receivedata().split("&");
          System.out.println("你的用户名为"+dataArray[0]);
          System.out.println("你的密码为"+dataArray[1]);//将得到的字符串以"&"为界限分割
          if(dataArray[0].equals("xiaojiehang")&&dataArray[1].equals("xjh")){
              senddata("登陆成功");
          }else{senddata("账号密码不匹配");} //分析数据并且双向输出,返回结/果给客户端

         release();
          //server.close(); //服务器一般不关闭,除了进行维护
      }
  }

}

将客户端收发数据封装:

public class LoginClient {

    public static void main(String[] args) throws IOException {
        System.out.println("-----Client-----");
        Scanner scanner=new Scanner(System.in);
        System.out.println("输入用户名:");
        String name=scanner.nextLine();
        System.out.println("输入密码:");
        String password=scanner.nextLine();
        Socket client=new Socket("localhost",8888);//建立连接,连接服务器的地址与端口
        new csend(client).send(name+"&"+password);
        new creceive(client).receive();


        client.close();

    }


   static class csend{//用于发送信息
       DataOutputStream dos;
       Socket client;
       public void send(String s){
           try {
               dos.writeUTF(s);
               dos.flush();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       public csend(Socket client) throws IOException {//构造函数,传入插座client,以及构造一个数据输出流用于发送数据
           this.client=client;
           try {
               dos=new DataOutputStream( client.getOutputStream() );//尽量选用data流
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       public void close() throws IOException {
           dos.close();
       }

    }
    static class creceive{//用于接收信息
        //得到服务器的返回值
        Socket client;
        DataInputStream dis;
        String result=null;
        public creceive(Socket client) throws IOException {
            this.client=client;
            try {
                dis=new DataInputStream( client.getInputStream() );
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        public void receive() throws IOException {
            try {
                result = dis.readUTF();
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println(result);
        }
        public void close() throws IOException {
            dis.close();
        }

        public String getResult() {
            return result;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值