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

时间:2023-02-18 11:12:15
------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

InetAddress类是Java中用于描述IP地址的类。它在java.net包中。在Java中分别用Inet4Address和Inet6Address类来描述IPv4和IPv6的地址。这两个类都是InetAddress的子类。由于InetAddress没有public的构造方法,因此,要想创建InetAddress对象,必须得依靠它的四个静态方法(有重载形式)。

InetAddress可以通过getLocalHost方法得到本机的InetAddress对象,也可以通过getByName、getAllByName和getByAddress得到远程主机的InetAddress对象。

InetAddress.getLocalHost()                        得到主机名和对应的IP

InetAddress.getByName(String host)        通过指定域名从DNS中得到相应的IP地址

InetAddress.getAllByName(String host)     通过指定域名从DNS中得到相应的所有IP地址

InetAddress.getByAddress(byte [] addr)    从DNS上得到域名对应的所有的IPInetAddress.getByAddress(string host, byte [] addr) 从DNS上得到域名对应的所有的IP,返回一个InetAddress类型的数组

第一个重载形式只需要传递byte数组形式的IP地址,getByAddress方法并不验证这个IP地址是否存在,只是简单地创建一个InetAddress对象。第二个重载形式多了一个host,这个host和getByName、getAllByName方法中的host的意义不同,getByAddress方法并不使用host在DNS上查找IP地址,这个host只是一个用于表示addr的别名。

在网页中如果要提交数据给web服务器,通常要把数据发送给web服务器,然后web服务器委派一个脚本对数据进行处理,返回一个相应。

通常发送数据的方法有两种:get和post。

(1)get方法是直接把数据跟在url的后面,以name=value进行传输,

每个数据之间用&进行分割,value中的空格用+替换,非字母数字用%替换,并后跟两个16进制数,这种编码方式称为URL编码。URLEncoder和URLDecoder

(2)post方法是通过URLConnection发送给服务器,编码方式和get一样。URLEncoder.encode(VALUE,"UTF-8");

一般在传输中文时会运用编码和解码。

Socket(TCP)

Socket是一个用于机器之间通信的类。

Socket客户端:

(1)Socket s = new Socket(ip,port);打开一个套接字,发送请求    

(2)InputStream istream = s.getInputStream();接收数据

(3)OutputStream ostream  = s.getOutputStream();发送数据

需要用PrintWriter和Scanner进行包装,并且注意PrintWriter的自动缓冲。

Socket服务器:注意多个客户端同时访问服务器的问题:多线程

(1)ServerSocket server = new ServerSocket(port);创建一个端口

(2)Socket s = server.accept();        只有当有客户端请求并连接,函数才会返回

(3)InputStream istream = s.getInputStream();接收数据

(4)OutputStream ostream  = s.getOutputStream();发送数据

需要用PrintWriter和Scanner进行包装,并且注意PrintWriter的自动缓冲。

我们在使用PrintWriter时需要使用println()函数;


当服务器或客户端任意一方请求结束通信,则立刻停止。

问题1:在套接字中会发生阻塞的地方:

(1)实例化Socket时,会阻塞。

(2)在in.nextLine()类似操作时会阻塞。

解决方法:

(1)对于第一个问题,解决方法:

  • Socket s = new Socket();建立无连接socket
  • s.connect(new InetSocketAddress(host,port),timeout);设置超时。

(2)对于第二个问题,解决方法是设置s.setSoTimeout(long)设置超时时间

问题2:当客户端想要关闭套接字时,但却不能确定服务器是否还在发送数据,但是只要一关闭就立刻断开。

解决方法:

socket.shutdownOutput()关闭输出流

socket.shutdownInput()关闭输入流

public class ServerD {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
// 监听端口
ServerSocket ss = new ServerSocket(10003);
System.out.println("服务器已启动:");
//System.out.println(InetAddress.getLocalHost());
Socket s=ss.accept();
   Scanner in = new Scanner(s.getInputStream());  
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);  
        String str = in.nextLine();  
        System.out.println(str);  
        s.shutdownInput();  
        System.out.println("关闭输入流");  
        Thread.sleep(5000);  
        out.println("输出:"+str);  
        s.close();  
}
}

public class ClientD {
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
            Socket sc=new Socket("2012-20130414LV", 10003);
            System.out.println("客户端启动!");
            Scanner in = new Scanner(sc.getInputStream());  
            PrintWriter out = new PrintWriter(sc.getOutputStream(),true);  
            out.println("Hello");//输出hello  
            sc.shutdownOutput(); //关闭输出流  
            System.out.println("关闭连接");  
            while(in.hasNextLine()){  
                System.out.println(in.nextLine());  
            }  
            sc.close();  
}
}

Socket(UDP)


聊天工具使用UDP非常多,因为我们通常也会遇到我们发给另一个人一条消息,另一个人却没有收到的情况。

DatagramPacket和DatagramSocket  数据报

示例代码:

public class DatagramClient {  
  
    public static void main(String[] args) throws Exception{  
        byte[]buf = new byte[1024];  
        DatagramPacket packet = new DatagramPacket(buf,1024);  
        DatagramSocket client = new DatagramSocket(9000);  
        client.receive(packet);  
        String str = new String(buf,0,packet.getLength());  
        System.out.println(packet.getAddress().getHostName()+":"+str);  
        client.close();  
    }  

public class DatagramServer {  

public static void main(String[] args)throws Exception {  
        DatagramSocket server = new DatagramSocket(3000);  
        String str = "hello world";  
        DatagramPacket packet = new DatagramPacket(str.getBytes(),str.length(),InetAddress.getLocalHost(),9000);  
        server.send(packet);  
        server.close();  
    }  

}

TCP与UDP区别

TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,

之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,

但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

TCP、UDP和HTTP的关系

1、TCP/IP是个协议组,可分为三个层次:网络层、传输层和应用层。
在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。
在传输层中有TCP协议与UDP协议。
在应用层有FTP、HTTP、TELNET、SMTP、DNS等协议。
因此,HTTP本身就是一个协议,是从Web服务器传输超文本到本地浏览器的传送协议。