TCP通信原理

TCP通信协议是一种牢靠的网络协议,它在通信的两端各建设一个Socket对象,从而在通信的两端造成虚构网络链路。一旦建设了虚构的网络链路,两端的程序就能够通过虚构链路进行通信

TCP发送数据

发送数据步骤

  1. 创立客户端的Socket对象(Socket) Socket(String host,int port)
  2. 获取输入流,写数据
    OutputStream getOutputStream()
  3. 开释资源 void close()

    //创立客户端的Socket对象(Socket)//Socket(InetAddress address,int port)创立流套接字并将将其连贯到指定IP地址的指定端口号Socket s = new Socket(InetAddress.getByName("192.168.1.66"),,port:10000);//alt enter 抛出异样//Socket(String host,int port)创立流套接字并将将其连贯到指定IP地址的指定端口号 //和后面那个一样 只是第一个参数能够间接是字符串地址Socket s = new Socket(host:"192.168.1.66",port:10000);//alt enter 抛出异样//获取输入流,写数据//OutputStream getOutputStream() 返回此套接字的输入流OutputStream os = s.getOutputStream();os.write(b:"hello,tcp,我来了".getBytes())//开释资源s.close();

TCP接收数据

接收数据步骤

  1. 创立服务器端的Socket对象(ServerSocket)
    ServerSocket(int port)
  2. 监听客户端连贯,返回一个Socket对象 Socket accept()
  3. 获取输出流,读数据,并把数据显示在控制台 InputStream getInputStream()
  4. 开释资源 void close()

    //创立服务器端的Socket对象(ServerSocket)//ServerSocket(int port)创立绑定到指定端口的服务器套接字ServerSocket ss = new ServerSocket(port:10000);//alt enter 抛出异样//Socket accept() 侦听要连贯到此套接字并承受它Socket s = ss.accept();//获取输出流,读数据,并把数据显示在控制台//InputStream getInputStream() 返回此套接字的输入流InputStream is = s.getInputStream();byte[] bys = new byte[1024];int len = is.read(bys);//拿到的是理论发送了多少数据String dataString = new String(bys,offset:0,len);sout("数据是:"+dataString);//开释资源s.close();ss.close();

TCP通信程序练习

练习1

  • 客户端:发送数据,接管服务器反馈
  • 服务器:接收数据,给出反馈
    客户端程序

    //创立客户端的Socket对象(Socket)Socket s = new Socket(host:"192.168.1.66",port:10000);//alt enter 抛出异样//获取输入流,写数据OutputStream os = s.getOutputStream();os.write(b:"hello,tcp,我来了".getBytes())//接管服务器反馈InputStream is = s.getInputStream();byte[] bys = new byte[1024];int len = is.read(bys);//拿到的是理论发送了多少数据String data = new String(bys,offset:0,len);sout("客户端:"+data);//开释资源s.close();

    服务器端程序

    //创立服务器端的Socket对象(ServerSocket)ServerSocket ss = new ServerSocket(port:10000);//alt enter 抛出异样//监听客户端连贯,返回一个Socket对象Socket s = ss.accept();//获取输出流,读数据,并把数据显示在控制台InputStream is = s.getInputStream();byte[] bys = new byte[1024];int len = is.read(bys);//拿到的是理论发送了多少数据String data = new String(bys,offset:0,len);sout("服务器:"+data );//给出反馈OutputStream os = s.getOutputStream();os.write("数据曾经收到".getBytes());//开释资源s.close();ss.close();

    练习2

  • 客户端:数据来自于键盘录入,直到输出的数据是886,发送数据完结
  • 服务器:接管到的数据在控制台输入
    客户端程序

    //创立客户端的Socket对象(Socket)Socket s = new Socket(host:"192.168.1.66",port:10000);//alt enter 抛出异样//数据来自于键盘录入,直到输出的数据是886,发送数据完结BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//封装输入流对象BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//字节输入流转化成字符流,而后用BufferedWriter写数据封装String line;while((line=br.readLine())!=null){//alt enter 抛出异样    //所输出的数据是886,发送数据完结    if("886".equals(line)){        break;    }    //如果不是,就获取输入流对象    //OutputStream os = s.getOutputStream();    //os.write(b:"hello,tcp,我来了".getBytes());    bw.write(line);    bw.newLine();    bw.flush();}//开释资源s.close();

    服务器端程序

    //创立服务器端的Socket对象(ServerSocket)ServerSocket ss = new ServerSocket(port:10000);//alt enter 抛出异样//监听客户端连贯,返回一个对应的Socket对象Socket s = ss.accept();//获取输出流,读数据,并把数据显示在控制台InputStream is = s.getInputStream();InputStreamReader isr = new InputStreamReader(is);BufferedReader br = new BufferedReader(isr);//下面三步合并为BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//输出流转化成字符流,再包装成BufferedReaderString line;while((line=br.readLine())!=null){//alt enter 抛出异样    sout(line);}//开释资源ss.close();

    练习3

  • 客户端:数据来自于键盘录入,直到输出的数据是886,发送数据完结
  • 服务器:接管到的数据写入文本文件
    客户端程序

    //创立客户端的Socket对象(Socket)Socket s = new Socket(host:"192.168.1.66",port:10000);//alt enter 抛出异样//数据来自于键盘录入,直到输出的数据是886,发送数据完结BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//封装输入流对象BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//字节输入流转化成字符流,而后用BufferedWriter写数据封装String line;while((line=br.readLine())!=null){//alt enter 抛出异样    //所输出的数据是886,发送数据完结    if("886".equals(line)){        break;    }    //如果不是,就获取输入流对象    //OutputStream os = s.getOutputStream();    //os.write(b:"hello,tcp,我来了".getBytes());    bw.write(line);    bw.newLine();    bw.flush();}//开释资源s.close();

    服务器端程序

    //创立服务器端的Socket对象(ServerSocket)ServerSocket ss = new ServerSocket(port:10000);//alt enter 抛出异样//监听客户端连贯,返回一个对应的Socket对象Socket s = ss.accept();//接收数据BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//输出流转化成字符流,再包装成BufferedReader//把数据写入文本文件BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myNet\\s.txt"));String line;while((line=br.readLine())!=null){//alt enter 抛出异样    bw.write(line);    bw.newLine();    bw.flush();}//开释资源bw.close();ss.close();

    练习4

  • 客户端:数据来自于文本文件
  • 服务器:接管到的数据写入文本文件
    客户端程序

    //创立客户端的Socket对象(Socket)Socket s = new Socket(host:"192.168.1.66",port:10000);//alt enter 抛出异样//数据来自于文本文件//封装文本文件的数据BufferedReader br = new BufferedReader(new FileReader(fileName:"myNet\\InetAddressDemo.java"));//封装输入流写数据BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//字节输入流转化成字符流,而后用BufferedWriter写数据封装//读数据,并且把它写出去String line;while((line=br.readLine())!=null){//alt enter 抛出异样    bw.write(line);    bw.newLine();    bw.flush();}//开释资源br.close();s.close();

    服务器端程序

    //创立服务器端的Socket对象(ServerSocket)ServerSocket ss = new ServerSocket(port:10000);//alt enter 抛出异样//监听客户端连贯,返回一个对应的Socket对象Socket s = ss.accept();//接收数据BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//输出流转化成字符流,再包装成BufferedReader//把数据写入文本文件BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myNet\\Copy.java"));String line;while((line=br.readLine())!=null){//alt enter 抛出异样    bw.write(line);    bw.newLine();    bw.flush();}//开释资源bw.close();ss.close();

    练习5

  • 客户端:数据来自于文本文件,接管服务器反馈
  • 服务器:接管到的数据写入文本文件,给出反馈

    • 呈现问题:程序始终期待
    • 起因:读数据的办法是阻塞式的

    客户端程序

    //创立客户端的Socket对象(Socket)Socket s = new Socket(host:"192.168.1.66",port:10000);//alt enter 抛出异样//数据来自于文本文件//封装文本文件的数据BufferedReader br = new BufferedReader(new FileReader(fileName:"myNet\\InetAddressDemo.java"));//封装输入流写数据BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//字节输入流转化成字符流,而后用BufferedWriter写数据封装//读数据,并且把它写出去String line;while((line=br.readLine())!=null){//alt enter 抛出异样    bw.write(line);    bw.newLine();    bw.flush();}//自定义完结标记//bw.write(str:"886");//bw.newLine();//bw.flush();//public void shutdownOutput()s.shutdownOutput();//接管服务器的反馈BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));String data = brClient.readLine();//期待读取数据sout("服务器的反馈:"+data);//开释资源br.close();s.close();

    服务器端程序

    //创立服务器端的Socket对象(ServerSocket)ServerSocket ss = new ServerSocket(port:10000);//alt enter 抛出异样//监听客户端连贯,返回一个对应的Socket对象Socket s = ss.accept();//接收数据BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//输出流转化成字符流,再包装成BufferedReader//把数据写入文本文件BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myNet\\Copy.java"));String line;while((line=br.readLine())!=null){//alt enter 抛出异样  还在这等着读数据呢 //   if("886".equals(line)){//        break;//    }    bw.write(line);    bw.newLine();    bw.flush();}//给出反馈BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); bwServer.write(str:"文件上传胜利");bwServer.newLine();bwServer.flush();//开释资源bw.close();ss.close();

    练习6

  • 客户端:数据来自于文本文件,接管服务器反馈
  • 服务器:接管到的数据写入文本文件,给出反馈,代码用线程进行封装,为每一个客户端开启一个线程
    客户端程序

    //创立客户端的Socket对象(Socket)Socket s = new Socket(host:"192.168.1.66",port:10000);//alt enter 抛出异样//数据来自于文本文件//封装文本文件的数据BufferedReader br = new BufferedReader(new FileReader(fileName:"myNet\\InetAddressDemo.java"));//封装输入流写数据BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//字节输入流转化成字符流,而后用BufferedWriter写数据封装//读数据,并且把它写出去String line;while((line=br.readLine())!=null){//alt enter 抛出异样    bw.write(line);    bw.newLine();    bw.flush();}//自定义完结标记//bw.write(str:"886");//bw.newLine();//bw.flush();//public void shutdownOutput()s.shutdownOutput();//接管服务器的反馈BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));String data = brClient.readLine();//期待读取数据sout("服务器的反馈:"+data);//开释资源br.close();s.close();

    服务器端程序

    //创立服务器端的Socket对象(ServerSocket)ServerSocket ss = new ServerSocket(port:10000);//alt enter 抛出异样while(true){    //监听客户端连贯,返回一个对应的Socket对象    Socket s = ss.accept();    //为每一个客户端开启一个线程    new Thread(new ServerThread(s)).start();}

    创立一个类实现线程

    public class ServerThread implements Runnable{   private Socket s;      public ServerThread (Socket s){       this.s = s;   }   //重写run办法   @Override   public void run(){      //接收数据,写到文本文件      BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//try catch捕捉异样      //BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myNet\\Copy.java"));      //解决名称抵触问题      int count = 0;      File file = new File(pathname:"myNet\\Copy["+count+"].java");      while(file.exists()){          count++;          file = new File(pathname:"myNet\\Copy["+count+"].java");      }      BufferedWriter bw = new BufferedWriter(new FileWriter(file));            String line;      while((line=br.readLine())!=null){          bw.write(line);          bw.newLine();          bw.flush();      }      //给出反馈      BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));       bwServer.write(str:"文件上传胜利");      bwServer.newLine();      bwServer.flush();      //开释资源      s.close();   }}