java网络编程基础

来源:互联网 发布:小游戏制作软件下载 编辑:程序博客网 时间:2024/05/29 16:30

InetAddress

首先介绍一个api : InetAdderss,该类用于封装一个IP地址,并且提供了一系列的IP地址相关操作的方法import java.net.InetAddress;import java.net.UnknownHostException;/* * InetAddress:此类表示互联网协议 (IP) 地址。  *  */public class InetAddressDemo {    public static void main(String[] args) throws UnknownHostException   {        //方法:static InetAddress getByName(String host)        //InetAddress address = InetAddress.getByName("hostname");        InetAddress address = InetAddress.getByName("192.168.1.107");//ip地址是唯一的        //System.out.println(address);//hostname/192.168.1.107 ipconfig        String hostAddress = address.getHostAddress();//192.168.1.107 返回IP地址        String hostName = address.getHostName();//hostname 返回主机名        System.out.println(hostAddress);        System.out.println(hostName);    }}

UDP协议

UDP协议:    UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。    由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如视频会议都使用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议。

DatagramPacket

UDP通信的过程就像是货运公司在两个码头间发送货物一样。在码头发送和接收货物时都需要使用集装箱来装载货物,UDP通信也是一样,发送和接收的数据也需要使用“集装箱”进行打包,为此JDK中提供了一个DatagramPacket(详细参考API)类,该类的实例对象就相当于一个集装箱,用于封装UDP通信中发送或者接收的数据。

DatagramSocket

DatagramPacket(详细参考API)数据包的作用就如同是“集装箱”,可以将发送端或者接收端的数据封装起来。然而运输货物只有“集装箱”是不够的,还需要有码头。在程序中需要实现通信只有DatagramPacket数据包也同样不行,为此JDK中提供的一个DatagramSocket类。DatagramSocket类的作用就类似于码头,使用这个类的实例对象就可以发送和接收DatagramPacket数据包,发送数据的过程如下图所示。

这里写图片描述

UDP的实现

发送端

代码案例:import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.SocketException;/* * 使用UDP协议发送数据的步骤        创建发送端Socket对象        创建数据并打包        发送数据        释放资源 *  * DatagramSocket:此类表示用来发送和接收数据,基于UDP协议的 *  * DatagramSocket() :创建Socket对象并随机分配端口号 * DatagramSocket(int port) :创建Socket对象并指定端口号 */public class SendDemo {    public static void main(String[] args) throws IOException  {        //创建发送端Socket对象        DatagramSocket ds = new DatagramSocket();        //创建数据并打包        /*         * DatagramPacket :此类表示数据报包         * 数据 byte[]         * 设备的地址 ip         * 进程的地址  端口号           DatagramPacket(byte[] buf, int length, InetAddress address, int port)          */        String s = "hello udp,im comming!";        byte[] bys = s.getBytes();        int length = bys.length;        InetAddress address = InetAddress.getByName("itheima");//发送给当前设备        int port = 8888;        //打包        DatagramPacket dp = new DatagramPacket(bys,length,address,port);        //发送数据        ds.send(dp);        //释放资源        ds.close();    }}

接收端

import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;/* * 使用UDP协议接收数据        创建接收端Socket对象        接收数据        解析数据        输出数据        释放资源 */public class ReceiveDemo {    public static void main(String[] args) throws IOException {        //创建接收端Socket对象        DatagramSocket ds = new DatagramSocket(8888);        //接收数据        //DatagramPacket(byte[] buf, int length)         byte[] bys = new byte[1024];        DatagramPacket dp = new DatagramPacket(bys,bys.length);        System.out.println(1);        ds.receive(dp);//阻塞方法,直到接受到数据        System.out.println(2);        //解析数据        //InetAddress getAddress() : 获取发送端的IP对象        InetAddress address = dp.getAddress();        //byte[] getData()  :获取接收到的数据,也可以直接使用创建包对象时的数组        byte[] data = dp.getData();        //int getLength()  :获取具体收到数据的长度        int length = dp.getLength();        //输出数据        System.out.println("sender ---> " + address.getHostAddress());        //System.out.println(new String(data,0,length));        System.out.println(new String(bys,0,length));        //释放资源        ds.close();    }}

TCP协议

TCP通信同UDP通信一样,都能实现两台计算机之间的通信,通信的两端都需要创建socket对象。区别在于,UDP中只有发送端和接收端,不区分客户端与服务器端,计算机之间可以任意地发送数据。而TCP通信是严格区分客户端与服务器端的,在通信时,必须先由客户端去连接服务器端才能实现通信,服务器端不可以主动连接客户端,并且服务器端程序需要事先启动,等待客户端的连接。在JDK中提供了两个类用于实现TCP程序,一个是ServerSocket类,用于表示服务器端,一个是Socket类,用于表示客户端。通信时,首先创建代表服务器端的ServerSocket对象,该对象相当于开启一个服务,并等待客户端的连接,然后创建代表客户端的Socket对象向服务器端发出连接请求,服务器端响应请求,两者建立连接开始通信。这里不再做ServerSocket和Socket的介绍,详细参考API

TCP协议的实现

客户端

import java.io.IOException;import java.io.OutputStream;import java.net.InetAddress;import java.net.Socket;/* * 使用TCP协议发送数据        创建发送端Socket对象(创建连接)        获取输出流对象        发送数据        释放资源    Socket(InetAddress address, int port)     Exception in thread "main" java.net.ConnectException: Connection refused: connect */public class ClientDemo {    public static void main(String[] args) throws IOException {        //创建发送端Socket对象(创建连接)        Socket s = new Socket(InetAddress.getByName("itheima"),10086);        //获取输出流对象        OutputStream os = s.getOutputStream();        //发送数据        String str = "hello tcp,im comming!!!";        os.write(str.getBytes());        //释放资源        //os.close();        s.close();    }}

服务端

import java.io.IOException;import java.io.InputStream;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;/* * 使用TCP协议接收数据        创建接收端Socket对象        监听(阻塞)        获取输入流对象        获取数据        输出数据        释放资源    ServerSocket:接收端,服务端Socket    ServerSocket(int port)     Socket accept()  */public class ServerDemo {    public static void main(String[] args) throws IOException  {        //创建接收端Socket对象        ServerSocket ss = new ServerSocket(10086);        //监听(阻塞)        Socket s = ss.accept();        //获取输入流对象        InputStream is = s.getInputStream();        //获取数据        byte[] bys = new byte[1024];        int len;//用于存储读到的字节个数        len = is.read(bys);        //输出数据        InetAddress address = s.getInetAddress();        System.out.println("client ---> " + address.getHostName());        System.out.println(new String(bys,0,len));        //释放资源        s.close();        //ss.close();    }}

需求:使用TCP协议发送数据,并将接收到的数据转换成大写返回

客户端

import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.InetAddress;import java.net.Socket;/*    需求:使用TCP协议发送数据,并将接收到的数据转换成大写返回    客户端发出数据    服务端接收数据    服务端转换数据    服务端发出数据    客户端接收数据 */public class ClientDemo {    public static void main(String[] args) throws IOException {        //创建客户端Socket对象        Socket s = new Socket(InetAddress.getByName("itheima"),10010);        //获取输出流对象        OutputStream os = s.getOutputStream();        //发出数据        os.write("tcp,im comming again!!!".getBytes());        //获取输入流对象        InputStream is = s.getInputStream();        byte[] bys = new byte[1024];        int len;//用于存储读取到的字节个数        //接收数据        len = is.read(bys);        //输出数据        System.out.println(new String(bys,0,len));        //释放资源        s.close();    }}

服务端

import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {    public static void main(String[] args) throws IOException {        //创建服务端Socket对象        ServerSocket ss = new ServerSocket(10010);        //监听        Socket s = ss.accept();        //获取输入流对象        InputStream is = s.getInputStream();        //获取数据        byte[] bys = new byte[1024];        int len;//用于存储读取到的字节个数        len = is.read(bys);        String str = new String(bys,0,len);        //输出数据        System.out.println(str);        //转换数据        String upperStr = str.toUpperCase();        //获取输出流对象        OutputStream os = s.getOutputStream();        //返回数据(发出数据)        os.write(upperStr.getBytes());        //释放资源        s.close();        //ss.close();//服务端一般不关闭    }}