黑马程序员----Java网络编程

来源:互联网 发布:mac下windows系统截图 编辑:程序博客网 时间:2024/06/04 19:46

——- android培训、java培训、期待与您交流! ———-

IP是互联网上的每一台计算机都有得一个唯一表示自己的标记。
IP地址使用4个8位的二进制数据表示,每8位之间使用圆点隔开,每个8位整数可以转换成一个0~255的十进制整数,因此我们一般看到的IP地址类似:192.168.1.1
分类:
IPv4:32位,分4段,0~255之间的十进制表示
IPv6:128位,分8段,0000~FFFF的十六进制数值,冒号分割。

java中InetAddress类要来表示IP地址,有两个子类:
Inet4Address(IPv4)
Inet6Address(IPv6)
常用方法

public static InnetAddress getByName(String host):根据主机获取对应的InetAddress对象public static InnetAddress getLocalHost():根据本机过得InetAddress对象public static InetAddress getByAddress(byte[] addr):根据原始Ip获得InetAddress对象public String getHostName():得到IP地址public boolean isReachable(int timeout):判断地址是否可以到达,同时指定超时时间

实例代码:

package xia.wt.net;import java.io.IOException;import java.net.InetAddress;import java.net.UnknownHostException;public class InetAddressDemo {    public static void main(String[] args) throws IOException {    //获得百度的InetAddress        InetAddress  iad = InetAddress.getByName("www.baidu.com");    //获得百度的InetAddress        byte[] ip = new byte[]{(byte)180,97,33,107};        InetAddress  iadd = InetAddress.getByAddress(ip);    //获得本地InetAddress        InetAddress  localiad = InetAddress.getLocalHost();        System.out.println(iad);        System.out.println(iadd);        System.out.println(localiad);    //检测是否可以到达百度主机//如果可以获得权限,则典型实现将使用 ICMP ECHO REQUEST;否则它将试图在目标主机的端口 7 (Echo) 上建立 TCP 连接。可能此方式被百度防火墙拦截,一只显示连接不上            System.out.println(iad.isReachable(1000000));    }}/**输出结果www.baidu.com/180.97.33.107/180.97.33.107TL-WR745N/192.168.1.107false*/

URL(Uniform Resource Locator)统一资源定位符,可以直接使用此类找到互联网上的资源如一个简单的网页。
一般由:协议名,资源所在主机,端口,资源名等部分组成。
常用构造方法:

URL(String spec):根据指定的地址实例化URL对象;URL(String protocol, String host, int port, String file) :实例化URL,并指定协议,主机,端口名字,资源文件public URLConnection openConnection():得到URLConnection 对象public final InputStream openStream():得到输入流

URLConnection封装访问远程网络资源一般方法的类,通过它可以建立与远程服务器的连接,检查远程资源的一些属性。

Java中URLEncoder可以为传递的内容编码,而URLDecoder可以为传递的内容解码;
URLEncoder:
public static String encode(String s,String enc):使用指定的编码机制将字符串转编码成application/x-www-form-urlencoded MIME字符串;
URLDecoder:
public static String decode(String s,String enc):使用指定编码机制对application/x-www-form-urlencoded MIME字符串解码

public class URLEncoderDemo {    public static void main(String[] args) throws UnsupportedEncodingException {        String s ="原始文字";        System.out.println(s);        //将s进行utf-8编码        s = URLEncoder.encode(s, "utf-8");        System.out.println(s);        //将s进行utf-8解码        s=URLDecoder.decode(s, "utf-8");        System.out.println(s);    }}/**输出结果原始文字%E5%8E%9F%E5%A7%8B%E6%96%87%E5%AD%97原始文字*/

TCP(Transmission Control Protocal)
是一种面向连接的、可靠的、基于字节流的传输层通信协议。
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元([1] MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体[1] 的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

Java中使用Socket实现TCP程序开发,使用此类可以方便的建立可靠的,双向的,持续的,点对点的通讯连接。
在Socket程序开发中,服务器端使用ServerScoket等待客户端的连接,在Java的网络程序中,每一个客户端都使用Socket对象表示。
在服务器端每次运行都要使用aceept()方法等待客户端连接,此方法执行之后服务器将进入阻塞状态,直到客户端连接之后程序才可以向下继续执行,此方法的返回类型是Socket,每一个Socket都表示每一个客户端连接对象。
Socket编程步骤:
1.建立网络连接;
2.打开连接到Socket的输入/输出流;
3.通过已打开的IO流进行读写操作;
4.关闭已打开的IO流和Socket;
示例代码:客户端和服务器端相互发送数据
客户端:

public class Client {    public static void main(String[] args) throws UnknownHostException, IOException {        //创建一个客户端对象        Socket s = new Socket(InetAddress.getLocalHost(),11260);        //准备输出、输入流        OutputStream os  = s.getOutputStream();        InputStream is = s.getInputStream();        //像服务器发送数据        os.write((Thread.currentThread().getName()+"客户端发来的消息").getBytes());        byte[] bs = new byte[1024];        int i = 0;        i = is.read(bs);        String str = new String(bs,0,i);        System.out.println(str);        //将接受到的数据返回给客户端        os.write(str.getBytes());        os.close();        is.close();        s.close();      }}

服务器端:

public class Servers {    public static void main(String[] args) throws IOException {        //创建ServerSocket对象并接受客户端发来的Socket对象        ServerSocket ss = new ServerSocket(11260);        Socket s = ss.accept();        //获得输入、输出流        InputStream is = s.getInputStream();        OutputStream os = s.getOutputStream();        //接受客户端发来的数据        byte[] bs =new byte[1024];        int i = 0;        i=is.read(bs);        String str = new String(bs,0,i);        System.out.println(str);        //像客户端送返回数据        os.write((str+"Echo").getBytes());        //再次接受客户端发来的数据         i = is.read(bs);        str = new String(bs,0,i);        System.out.println(str);        os.write((str+"Echo").getBytes());        //通讯结束,关闭资源        os.close();        is.close();        s.close();        ss.close();    }}

一个ServerSocket在一个时间段内只能为一个Socket客户端提供服务,要想同时对多个Socket提供服务可以使用多线程。
实例代码:
服务端:

package xia.wt.net;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 ThreadSocketSer {    public static void main(String[] args) throws IOException {        //创建服务器对象        ServerSocket ss = new ServerSocket(8888);        /*死循环接受客户端请求,没有客户端连接就一只阻塞主线程,        有客户端连接就将就收到的客户端交给一个新线程处理,主线程继续等待客户端*/        while(true){            //接受客户端请求或阻塞在此处            Socket s = ss.accept();            //有客户端连接就交给新线程处理            new Thread(new ThreadsServer(s)).start();;        }    }}class ThreadsServer implements Runnable{    private Socket s;    //接受主线程传来的客户端信息    public ThreadsServer(Socket s){        this.s = s;    }    @Override    public void run() {        try (//创建输入输出流                BufferedReader  bf = new BufferedReader(new InputStreamReader(s.getInputStream()));                PrintWriter pw  = new PrintWriter(s.getOutputStream(),true);                ){                boolean tag = true;                while(tag){                    //循环接受客户端数据并应答,直到客户端发送的数据是以5结尾                    String s = bf.readLine();                    if(s.endsWith("4")){tag=false;}                    System.out.println(s);                    pw.println(s+"--Echo+"+Thread.currentThread().getName());            }                bf.close();pw.close();s.close();        } catch (IOException e) {            e.printStackTrace();        }           }}

客户端:

public class ThreadSocketCli{    public static void main(String[] args) {        //主线程创建5个线程,分别向服务端发送数据        for(int j =0;j<5;j++){            new Thread(new ThreadClient(),"线程"+j).start();        }    }}class ThreadClient implements Runnable{    @Override    public void run() {        try(//创建客户端对象并创建输入输出流                Socket s = new Socket(InetAddress.getLocalHost(),8888);                PrintWriter pw = new PrintWriter(s.getOutputStream(),true);                BufferedReader bf= new BufferedReader(new InputStreamReader(s.getInputStream()));                ) {            for (int i = 0; i < 5; i++) {                //向服务端发送包含请求次数的数据                pw.println(Thread.currentThread().getName()+"for"+i);                //打印服务端返回的数据                System.out.println(bf.readLine());            }            pw.close();            bf.close();            s.close();        } catch (IOException e) {            e.printStackTrace();        }    }}

UDP(User Datagram Prptocol)

UDP协议全称是用户数据报协议 ,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

UDP开发中使用DatagramPacket包装一条要发送的信息,之后使用DatagramSocket完成发送操作。
实例代码
客户端向服务端发送数据
客户端:

public class UDPClient {    public static void main(String[] args) throws IOException {        //准备要发送的数据,并打包为DatagramPacket        byte[] bs = "客户端发来的数据".getBytes();        DatagramPacket dp=new DatagramPacket(bs,bs.length,InetAddress.getLocalHost(),8888);        //发送数据        DatagramSocket da = new DatagramSocket(8080);        da.send(dp);    }}

服务端:

public class UDPServer {    public static void main(String[] args) throws IOException {        //准备数据包,用于接受数据        byte[] bs = new byte[1024];        DatagramPacket dp =new DatagramPacket(bs,bs.length);        //接受数据并打印        DatagramSocket da = new DatagramSocket(8888);        da.receive(dp);        System.out.println(new String(bs,0,dp.getLength()));    }}

TCP & UDP简单对比
1。基于连接与无连接 ;
2。对系统资源的要求(TCP较多,UDP少) ;
3。UDP程序结构较简单 ;
4。流模式与数据报模式 ;
5。TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证;

0 0
原创粉丝点击