黑马程序员---网络编程(一)

来源:互联网 发布:无尽之剑3宝石数据修改 编辑:程序博客网 时间:2024/05/01 08:27
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------


网络编程

概述:

(1)网络模型

   OSI参考模型

   TCP/IP参考模型

(2)网络通讯要素

   IP地址

   端口号

   传输协议

(3)网络通讯前提:

   找到对方IP数据要发送到指定端口。为了标示不同的应用程序,所以给这些网络应用程序都用数字进行标示。

   这个表示就叫端口。

   定义通信规则。这个规则称为通信协议,国际组织定义了通用协议TCP/IP

网络通讯要素:

IP地址:InetAddress

网络中设备的标识

不易记忆,可用主机名

本地回环地址:127.0.0.1 

主机名:localhost 

端口号

用于标识进程的逻辑地址,不同进程的标识

有效端口:0~65535,其中0~1024系统使用或保留端口。 

传输协议

通讯的规则

常见协议:TCP,UDP

UDP:将数据及源和目的封装成数据包中,不需要建立连接

每个数据报的大小在限制在64k内

因无连接,是不可靠协议

不需要建立连接,速度快 

TCP:建立连接,形成传输数据的通道。

在连接中进行大数据量传输

通过三次握手完成连接,是可靠协议

必须建立连接,效率会稍低

     三次握手:

          第一次:我问你在么?

          第二次:你回答在。

          第三次:我反馈我知道你在。

UDP传输:

需求:通过udp传输方法,将一段文字数据发送出去;

思路:

1,建立DatagramSocket服务。

2,提供数据,并将数据封装到数据包中。

3,通过socket服务的发送功能,将数据包发出去。

4,关闭资源。

发送端:

     class UDPSend{

          public staticvoid main(String[] args) throws Exception{

            DatagramSocketds = new DatagramSocket();

            byte[] buf ="这是UDP发送端".getBytes();

            DatagramPacketdp = newDatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10000);

            ds.send(dp);

            ds.close();

             }

       }

接收端:

    class UDPRece{

         public staticvoid main(String[] args) throws Exception{

           DatagramSocketds = new DatagramSocket(10000);

           byte[] buf =new byte[1024];

           DatagramPacketdp = new DatagramPacket(buf,buf.length);

           ds.receive(dp);//将发送端发送的数据包接收到接收端的数据包中

           String ip =dp.getAddress().getHosyAddress();//获取发送端的ip

           String data= new String(dp.getData(),0,dp.getLength());//获取数据

           int port =dp.getPort();//获取发送端的端口号

           sop(ip+":"+data+":"+port);

           ds.close();

            }

      }

//*编写一个聊天程序*//

分析:有收数据的部分和发数据的部分。这两部分同时执行。那就需要使用到多现程技术。

一个线程控制收,一个线程控制发。因为收和发动作是不一致的,

所以要定义两个run方法。而且这两个方法要封装不同的类中。

发送端:

     class UDPSendimplements Runnable{

            privateDatagramSocket ds;

            publicUDPSend(){}

        publicUDPSend(DatagramSocket ds){

             this.ds=ds;

         }

        public voidrun(){

        try{

           BufferedReaderbufr = new BufferedReader(new InputStreamReader(System.in));

                 Stringline = null;

            while((line= bufr.readLine())!=null){

                  if("886".equals(line))

                       break;

              byte[]buff = line.getBytes();

              DatagramPacket dp = newDatagramPacket(

                               buf,buf.length,InetAddress.getByName("127.0.0.1"),10000);

              ds.send(dp);

           }

      }

             catch(Exceptione){

                  thrownew RuntimeException("发送失败");

                 }

             }

       }

接收端:

     class UDPReceimplements Runnable{

          private DatagramSocket ds;

          publicUDPSend(){}

          publicUDPSend(DatagramSocket ds){

             this.ds=ds;

      }

          public voidrun(){

          try{

              while(true){   

                   byte[]buf = new byte[1024];

                   DatagramPacketdp = new DatagramPacket(buf,buf.length);

                   ds.receive(dp);//将发送端发送的数据包接收到接收端的数据包中

                  Stringip = dp.getAddress().getHosyAddress();//获取发送端的ip

                  Stringdata = new String(dp.getData(),0,dp.getLength());//获取数据

                  intport = dp.getPort();//获取发送端的端口号

                        sop(ip+":"+data+":"+port);     

            }

      }

               catch(Exceptione){

                     throw new RuntimeException("接收失败");

          }

      }

  }

测试类:

   class UDPTest{

       public staticvoid main(String[] args){

           DatagramSocket sendSocket = new DatagramSocket();

           DatagramSocket receSocket = newDatagramSocket(10000);

            new Thread(new UDPSend(sendSocket)).start();

            newThread(new UDPRece(receSocket)).start();

      }

 }

 

TCP传输:

Socket和ServerSocket建立客户端和服务端。

客户端:通过查阅socket对象,发现在该对象建立时,就可以去连接制定主机。因为tcp是面向对象的,所以在建立socket服务时,就要有服务端存在,并连接成功、形成通路之后,在该通道进行数据的传输。

TCP传输流程:

     客户端:

         1、建立Socket服务,并制定要连接的主机和端口;

         2、获取Socket流中的输出流OutputStream,将数据写入流中,通过网络发送给服务端;

         3、获取Socket流中的输出流InputStream,获取服务端的反馈信息;

         4、关闭资源。

      服务端:

         1、建立ServerSocket服务,并监听一个端口;

         2、获取连接过来的客户端对象。通过ServerSocket的accept方法。没有连接就会等,所以这个方法是阻塞式的;

         3、使用客户端对象的读取流获取客户端发送过来的数据;

         4、通过客户端对象的写入流反馈信息给客户端;

         5、关闭资源;

练习代码1:建立一个文本转换服务端,客户给服务端发送文本,服务端将数据转换成大写后返回给客户端,当客户端输入over时,转换结束

//客户端:

class TCPClient{

     public staticvoid main(String[] args){

          Socket s =new Socket("127.0.0.1",10000);

          BufferedReaderbufr = new BufferedReader(new InputStreamReader(System.in));

          BufferedWriterbufOut = new BufferedWriter(new OutputStreamWriter(

                             s.getOutputStream()));

          BufferedReaderbufIn = new BufferedReader(new InputStreamReader(

                            s.getInputStream()));

          String line= null;

          while((line= bufr.readLine())!=null){

          if("over".equals(line))

                 break;

           bufOut.write(line);

           bufOut.newLine();

           bufOut.flush();

           StringretVal = bufIn.readLine();

                   sop("server:"+retVal);

                         }

            bufr.close();

            s.close();

    }

 }

//服务端:

class TCPServer{

     public staticvoid main(String[] args){

        ServerSocketss = new ServerSocket(10000);

        Socket s =ss.accept();

        String ip =s.getInetAddress().getHostAddress();

             sop(ip);

                               

        BufferedReaderbufIn = new BufferedReader(new InputStreamReader(

                          s.getInputStream()));

        BufferedWriterbufOut = new BufferedWriter(new OutputStreamWriter(

                           s.getOutputStream()));

 

          while((line = bufIn.readLine())!=null){

                bufOut.write(line.toUpperCase());

                bufOut.newLine();

                bufOut.flush();

    }

                s.close();

                ss.close();

     }

 }


0 0