黑马程序员Java学习日记(8)网络编程

来源:互联网 发布:沉浸式英语教学软件 编辑:程序博客网 时间:2024/05/16 09:38

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

 

黑马程序员Java学习日记(8)网络编程

1.概述

(1)网络模型:1OSI参考模型

                      2TCP/IP参考模型

图例:

(2)网络通讯要素:

                 1IP地址

                 2、端口号

                 3、传输协议

   1、IP地址:比如说A主机想给B主机发一个信息,那么A主机就先得找到B 机,那么B主机应该有一个标识,方便A

                           主机找到它,那么这个标识就是IP地址。             

   2IP地址特点:

                      2.1、是网络设备的标识。

               2.2、不易记忆,可用主机名。

               2.3、本地回环地址:127.0.0.1 主机名:localhost

 

   3、端口号:

          A主机现在找到B主机了,但是数据发到哪里呢?A主机想发数据,那么A主机里面必须要应用程序编辑数据,比如所QQ,那么你发给B主机,B主机应该也有对应的应用程序来接收数据,所以为了标识这些应用程序,给这些网络应用程序进行数字标识。比如QQ4000YY3000。那么AQQ就发信息了,它要发的信息是BIP地址的4000这个数字所对应的应用程序上。那么为了方便称呼这个数字,就叫 做 端口,它是一个逻辑端口。              

  4、端口的作用及数字表示:

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

              4.2、有效端口:0-65535,其中0-1024系统使用或保留端口。

  5、传输协议:

         两个主机想进行通讯,就必须定义一个通讯规则,这个规则就称为协议,协议有UDPTCP/IP,这两种比较常见。

              

 (3)TCP和UDP:

1、UDPUDP是面向无连接的,那么是面向无连接呢?它有两端,因为网络通

   讯只有两端,用UDP发数据的时候,不管对方在不在,它也要把数据打包发 

   过去,在的话就接收到了,不在的话就这个包就丢掉了。所以用UDP发数据

   的时候不需要连接。

 2、 UDP特点:

              2.1、面向无连接,不需要连接。

              2.2、每个数据包的大小限制在64k内(数据会被封包)。

              2.3、是不可靠协议,因为无连接。

              2.4、速度快,因为不需要连接。

 3、什么时候用UDP:在不需要保证丢失数据的情况下,需要的是速度,就用UDP比如:视频聊天。             

 4、TCPTCP是面向连接的,要想通过TCP进行通话,对方必须在,先去确定对方在,然后在进行数据的发送。

 5、那么怎么确定对方在呢?

       是通过三次握手来完成的。

 6、那么是三次握手呢?

      比如说AB要进行通讯了,那么A先发一些信息给B,确认B在不在,如果B在,那么B就会给A回信息,完了B并不

    知道A接收到了信息,所以A接收到B发送回来的信息以后再给B发一个信息,说明已接收到信息。

 7、结论:

      通过三次握手就能完成TCP这个传输通道的建立,连接了以后,数据在连接通路里边传输就可以了。

 8、TCP的特点:

             8.1、建立连接,形成传输数据的通道(通过三次握手完成的)。 

             8.2、在连接中进行大数据量传输,不需要封包。

             8.3、通过三次握手完成连接,是可靠协议。如果有一方断开,那么数据就不传了。   

             8.4、必须建立连接,效率会稍低。而且消耗资源。

 9、什么时候用到TCP呢?

      比如下载的时候会用到,因为不能丢失数据。

(4)Socket:

Socket: 其实我们所说的网络编程就是Socket编程,它是两个程序连接的端

      点(这两个程序分别在2个主机上),想要传输数据,就先得有Socket

Socket的特点:

       1Socket就是为网络服务提供的一种机制。

              2、通信的两端都有Socket

              3、网络通信其实就是Socket间的通信。

              4、数据在两个Socke通过IO传输。

 

(5)UDP发送端:

建立发送端:

  1、建立UDPSocket服务,也就是先建立端点,发送端点。

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

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

  4、关闭资源。

代码例子:

需求:

通过UDP传输方式,将一段文字数据发送出去。

import java.net.*;

class  UdpSend

{

    public static void main(String[] args)throws Exception 

   {

          //创建UDP服务,通过DatagramSocket对象。

          DatagramSocket ds= new DatagramSocket();

         //确定数据,并封装成数据包。

         byte[]buf = "udp ni hao".getBytes();

         DatagramPacket dp=new DatagramPacket(

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

        //通过send方法将数据包发出去。

        ds.send(dp);

        ds.close();

     }

}

打印没有结果,因为是无连接的,还没有接收端。

(6)UDP接收端:

需求:

定义一个应用程序,用于接收UDP协议传输的数据并处理数据。

代码例子:

import java.net.*;

class  UdpSend

{

     public static void main(String[] args)throws Exception 

     {

          //创建UDP服务,通过DatagramSocket对象。

          DatagramSocket ds= new DatagramSocket();

         //确定数据,并封装成数据包。

         byte[]buf = "udp ni hao".getBytes();

         DatagramPacket dp=new DatagramPacket(

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

        //通过send方法将数据包发出去。

        ds.send(dp);

        ds.close();

     }

}

接收到了客户端发来的信息。

(7)UDP键盘录入方式数据:

代码例子:
import java.net.*;

import java.io.*;

class UdpSend2 

{

     public static void main(String[] args)throws Exception 

    {

         //创建UDP服务,通过DatagramSocket对象。

         DatagramSocket ds= new DatagramSocket();

         //获取键盘录入。

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

        String line =null;

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

        {

           if("over".equals(line))

               break;

          byte[] buf=line.getBytes();

           //定义数据包。

          DatagramPacket dp=new DatagramPacket(

          buf,buf.length,InetAddress.getByName("121.25.34.18"),10001);

          //通过send方法将数据包发出去。

          ds.send(dp);

        }

       ds.close();

     }

}

接收端:

代码例子:
import java.net.*;

import java.io.*;

class  UdpRece2

{

     public static void main(String[] args)throws Exception 

     {

        //创建udp Socket服务,建立端点。

       DatagramSocket ds= new DatagramSocket(10001);

        while(true)

        {

           byte[] buf=new byte[1024];

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

           ds.receive(dp);

           String ip =dp.getAddress().getHostAddress();

           String data =new String(dp.getData(),0,dp.getLength());

           int port=dp.getPort();

           System.out.println(ip+".."+data+".."+port);

           ds.close();

         }

      }

}

 

(8)UDP聊天:

需求:用多线程的技术完成聊天软件的编写,不是开两个进程,而是一个进程,多个线程来完成。

代码例子:

import java.net.*;

import java.io.*;

class  Send implements Runnable

{

     private DatagramSocket ds;

     public Send(DatagramSocket ds)

     {

           this.ds=ds;

     }

     public void run()

     {

          try

         {

             BufferedReader bufr = new BufferedReader(

             new InputStreamReader(System.in));

             String line =null;

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

            {

                if("over".equals(line))

                      break;

               byte[] buf=line.getBytes();

              //定义数据包。

               DatagramPacket dp=new DatagramPacket(

               buf,buf.length,InetAddress.getByName("121.25.34.18"),10001);

               //通过send方法将数据包发出去。

               ds.send(dp);

               ds.close();

            }

        }

        catch (Exception e)

        {

            throw new RuntimeException("发送失败");

        }

     }

}

class  Rece implements Runnable

{

     private DatagramSocket ds;

     public Rece(DatagramSocket ds)

     {

         this.ds=ds;

      }

      public void run()

     {

         try

        { 

             while(true)

             {

                byte[] buf=new byte[1024];

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

               ds.receive(dp);

               String ip =dp.getAddress().getHostAddress();

               String data =new String(dp.getData(),0,dp.getLength());    

               System.out.println(ip+".."+data);

               ds.close();

             }

        }

       catch(Exception e)

       {

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

        }

     }

}

class ChatDemo

{

     public static void main(String[] args)throws Exception

     {

         DatagramSocket sendsocket =new DatagramSocket();

         DatagramSocket recesocket =new DatagramSocket(10002);

         new Thread(new Send(sendsocket)).start();

         new Thread(new Rece(recesocket)).start();

      }

}

 

(9)TCP传输:

客户端:

1、客户端:Socket

2、建立客户端和服务端。

3、建立连接以后通过Socket中的IO流进行数据的传输。

4、关闭服务。

 

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

 

需求:给服务端发送一个文本数据。

代码例子:

import java.io.*;

import java.net.*;

class  TcpClient

{

     public static void main(String[] args) throws Exception

     {

          //创建客户端的Socket服务。

         Socket s = new Socket("121.25.34.18",10005);

         /*如果服务一旦建立成功,通路有了以后,就可以获取到

         Socket流里面的输出流或者输入流,来完成对数据的操作。*/

 

        //发送数据,应该获取Socket流中的输出流。

        OutputStream out=s.getOutputStream();

        out.write("tcp nihao".getBytes());

        s.close();

     }

}

 

(10)服务端:

服务端没有流对象,当A客户端连接到服务端,形成通路,那么服务端就可以用A的流对象和A进行通讯。

 

需求:定义端点接收数据并打印在控制台上。

服务端:

1、建立服务端的Socket服务,ServerSocket;

   这个数据一建立就需要绑定端口。

2、获取连接过来的客户端对象,通过erverSocketaccept方法,如果没有连接

   就会等,所以这个方法是阻塞式的。

3、客户端发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户

   端的读取流来读取发过来的数据,并打印在控制台上。

4、关闭服务端。

 

代码例子:

 import java.io.*;

import java.net.*;

class  TcpServer

{

     public static void main(String[] args) throws Exception

     {

         //创建服务端的Socket服务。

         ServerSocket ss = new ServerSocket(10005);

         //获取客户端。

        Socket s=ss.accept();

        //获取客户端地址。

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

         System.out.println(ip);

         //获取读取流。

        InputStream ips =s.getInputStream();

        byte[] buf =new byte[1024];

        int i =0;

        System.out.println(new String(buf,0,i));

        s.close();

     }

}

 

(11)TCP练习:

需求:客户端给服务端发送文本,服务端会将文本反转以后再返回给客户端。而且客户端可以不断的进行文本转换。当客户端输入over时,转换结束。

 

代码例子:

客户端:

import java.io.*;

import java.net.*;

public class ClientDemo 

{

    public static void main(String[] args) throws Exception 

    {

        //建立Socket服务,指定地址和端口。

        Socket s = new Socket("121.25.34.18", 10019);

        // 定义读取键盘的流对象。

        BufferedReader buf = new BufferedReader(

        new InputStreamReader(System.in));

        // 将数据写入到Socket输出流,发给服务端,需要提高效率。

        BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

        // 创建一个Socker读取流,读取服务端返回的信息,需要提高效率。

        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

        String line = null;

        while ((line = buf.readLine()) != null) 

        {

           //定义一个结束标记,当录入over,就停止录入。

           if("over".equals(line))     

               break;

            //将数据发送给服务端。

            bufOut.write(line);

            bufOut.newLine();

            bufOut.flush();

            //读取服务端反馈回来的数据。

            String str = bufIn.readLine();

            //打印返回来的数据。

            System.out.println(str);      

        }

       //关闭客户端。

       s.close();

      //关闭键盘录入。

       buf.close();

    }

}

 

服务端:

代码例子:

import java.io.*;

import java.net.*;

public class SenverDemo 

{

    public static void main(String[] args) throws Exception

    {

        //建立ServerSocket服务,指定端口。

        ServerSocket ss = new  ServerSocket(10019);

        System. out .println("服务端已创建成功");

        System. out .println("等待客户机的链接");

        //获取连接过来的客户端对象。

        Socket s=ss.accept();

        //获取客户端地址。

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

         System. out .println(ip); 

         //创建一个Socket读取流,读取客户端发过来的数据,需要提高效率。

         BufferedReader bufIn =new BufferedReader(new InputStreamReader(s.getInputStream()));

          //创建一个Socket输出流,把数据反转后发回客户端。

          BufferedWriter bufOut =new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

          String line =null;

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

          {

              //把读的数据存到StringBuilder里面。

             StringBuilder sb  =new StringBuilder(line); 

             //字符串反转处理。

             String str=sb.reverse().toString(); 

             //服务器本地输出客户端发来的数据。

             System. out .println(line); 

             //将反转后的数据发回给客户端。

             bufOut.write(str);

             bufOut.newLine();

             bufOut.flush();

          }

         //关闭客户端。

         s.close();

        //关闭服务端。

        ss.close();

     }

}

 

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

 

0 0
原创粉丝点击