网络编程

一、网络编程

就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换

二、网络模型

OSI参考模型

  • 应用层:主要是一些终端的应用,比如FTP(各种文件下载)、WEB(IE浏览)、QQ之类的
  • 表示层:主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩(也就是把计算机能够识别的东西转换成人能识别的东西,如图片、声音等)
  • 会话层:通过传输层建立数据传输的通路。主要在你的系统之间发起会话或者接收会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)
  • 传输层:定义了一些传输数据的协议和端口号,如:TCP、UDP
  • 网络层:主要从下层接收到的数据进行IP地址的封装与解封装、这一层数据叫数据包
  • 数据链路层:主要将从下层接收到的数据进行MAC地址的封装与解封装。这一层数据叫帧。在这一层工作的设备叫交换机,数据通过交换机来传输
  • 物理层:定义物理设备标准。主要作用是传输比特流。

TCP/IP参考模型

  • 应用层
  • 传输层
  • 网络层
  • 数据链路层

三、网络编程三要素

  • IP地址:网络中计算机的唯一标识
  • 端口号
  • 协议

UDP:

  • 把数据打包
  • 数据有限制
  • 不建立连接
  • 速度快
  • 不可靠

举例:发短信、扣扣聊天

TCP:

  • 建立连接通道
  • 数据无限制
  • 速度慢
  • 可靠

举例:打电话、语音聊天

两个DOS命令:

ipconfig:查看本机IP地址

ping + IP地址:测试本机与指定的ip地址间的通信是否有问题(127.0.0.1表示本机)

四、获取ip地址或者主机名

import java.net.InetAddress;
import java.net.UnknownHostException;

public class InetAddressDemo {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress address = InetAddress.getByName("192.168.2.121");
        String name = address.getHostName();
        String ip = address.getHostAddress();
        System.out.println(name + "----" + ip);
    }
}

五、网络套接字(Socket)

Socket包含了:IP地址+端口

1、概念:

网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字

2、Socket原理机制

  • 通信的两端都有Socket
  • 网络通信其实就是Socket间的通信
  • 数据在两个Socket间通过IO传输

网络编程

3、UDP协议发送与接收数据

 接收端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
 * UDP协议接收数据:
 * A:创建接收端Socket对象
 * B:创建数据包(接收容器)
 * C:调用Socket对象的接收方法接收数据
 * D:解析数据包并显示在控制台
 * E:释放资源
 * */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket(10086);    
        byte[] bys= new byte[1024];
        DatagramPacket dp = new DatagramPacket(bys,bys.length);
        ds.receive(dp);    
        //解析数据
        System.out.println(dp.getAddress().getHostAddress() + ":" + new String(dp.getData(),0,dp.getLength()));
        ds.close();
    }
}

发送端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
 * UDP协议发送数据:
 * A:创建发送端Socket对象
 * B:创建数据,并把数据打包
 * C:调用Socket对象的发送方法发送数据包
 * D:释放资源
 * */
public class SendDemo {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();
        byte[] bys = "hello,udp,我来了".getBytes();
        DatagramPacket dp = new DatagramPacket(bys, bys.length,InetAddress.getByName("192.168.2.121"),10086);
        ds.send(dp);
        ds.close();
    }
}

改进版:

接收端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/*
 * UDP协议接收数据:
 * A:创建接收端Socket对象
 * B:创建数据包(接收容器)
 * C:调用Socket对象的接收方法接收数据
 * D:解析数据包并显示在控制台
 * E:释放资源
 * */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket(10086);
        while (true) {
            byte[] bys = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bys, bys.length);
            ds.receive(dp);
            // 解析数据
            System.out.println(dp.getAddress().getHostAddress() + ":" + new String(dp.getData(), 0, dp.getLength()));
        }
    }
}

发送端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
 * 数据来自于键盘录入
 * 
 * */
public class SendDemo {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while((line = br.readLine())!=null){
            if("886".equals(line))
                break;
            byte[] bys = line.getBytes();
            DatagramPacket dp = new DatagramPacket(bys, bys.length,InetAddress.getByName("192.168.2.121"),10086);
            ds.send(dp);
        }
        ds.close();
    }
}

4、TCP协议发送与接收数据

服务端:

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * TCP协议接收数据:
 * A:创建接收端的Socket对象
 * B:监听客户端连接,返回一个对应的Socket对象
 * C:获取输入流,读取数据显示在控制台
 * D:释放资源
 * 
 * */
public class ServerDemo {
    public static void main(String[] args) throws IOException{
        ServerSocket ss = new ServerSocket(8888);
        
        //监听客户端连接
        Socket st = ss.accept();
        
        InputStream is = st.getInputStream();
        
        byte[] bys = new byte[1024];    
        System.out.println(st.getInetAddress().getHostAddress()+" : "+new String(bys,0,is.read(bys)));
        st.close();    
        //ss.close();   这个不应该关闭
    }
}

客户端:

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
/*
 * TCP协议发送数据:
 * A:创建发送端的Socket对象
 *   这一步如果成功,就说明连接已经建立成功
 * B:获取输出流,写数据
 * C:释放资源
 * TCP协议一定要先开服务器
 * 
 * */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        Socket st = new Socket("192.168.2.121", 8888);    
        OutputStream os = st.getOutputStream();
        os.write("hello,tcp,我来了".getBytes());
        st.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 {
        ServerSocket ss = new ServerSocket(9999);
        
        Socket s = ss.accept();
        
        InputStream is = s.getInputStream();
        
        byte[] bys = new byte[1024];
        
        System.out.println("server" + new String(bys,0,is.read(bys)));
        
        OutputStream os = s.getOutputStream();
        os.write("数据已收到".getBytes());
        
        s.close();

    }
}

客户端:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException{
        Socket s = new Socket("192.168.2.121",9999);
        
        OutputStream os = s.getOutputStream();
        os.write("今天天气很好".getBytes());
        
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        System.out.println("Client"+new String(bys,0,is.read(bys)));

        s.close();
    }
}