干货满满!!!网络编程(TCP网络通信+UDP网络通信+TCP和UDP的通信交互)

网络编程

学习本节网络编程,最好配合Java网络编程概述(IP和端口号、网络通讯协议、TCP和UDP协议的概述及其区别)一起学习,这样能够达到理论与实际相结合,可以对网络编程由一个更加全面的学习。

Socket套接字

概述

1、利用套接字(Socket)开发网络应用早已被广泛的采用,以至于成为事实上的标准。

2、通信的两端都要有套接字(Socket),是两台机器间通信的端点。

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

4、Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。

5、通常情况下主动发其通信的应用程序属于客户端,等待通信请求的是服务端。

Socket中的常用方法

返回值 方法名 功能
InetAddress getLocalAddress() 返回对方Socket中的IP的InetAddress对象
int getLocalPort() 返回本地Socket中的端口号
InetAddress getInetAddress() 返回对方Socket中的IP地址
int getPort() 返回对方Socket中的端口号
void close() 关闭Socket
InputStream getInputStream() 获取与Socket相关联的字节输入流,用于读数据
OutputStream getOutputStream() 获取与Socket相关联的字节输出流,用于写数据
Socket accept() 监听客户端的连接请求,返回与该客户端通信的Socket对象
void close() 关闭监听Socket
InetAddress getInetAddress() 返回此服务器套接字的本地地址
int getLocalPort() 返回此套接字在其上监听的端口号
SocketAddress getLocalSocketAddress() 返回此套接字绑定的端点的地址

TCP网络通信

客户端

工作过程

客户端Socket的工作过程包含以下四个基本步骤

**1、创建Socket:**根据指定服务端的IP地址或端口号构造Socket类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。

**2、打开连接到Socket的输入/出流:**使用getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输。

**3、按照一定的协议对Socket进行读/写操作:**通过输入流读取服务器放入线路的信息(但不能读取子集放入线路的信息),通过输出流将信息写入进程。

**4、关闭Socket:**断开客户端到服务器的连接,释放线路。

创建客户端

1、客户端程序可以使用Socket类创建对象,创建的同时会自动向服务器方发起连接。Socket的构造方法是:

(1)Socket(String host,int port):向服务器(域名host,端口号port)发起TCP连接,若成功,则创建Socket对象,否则抛出异常。

(2)Socket(InetAddress address,int port):根据InetAddress对象所代表的IP地址以及端口号port发起连接。

2、客户端建立socketAtClient对象的过程就是像服务器发送套接字请求。

代码示例——创建客户端

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

public class Client {
    
    
    /*这是一个程序入口*/
    public static void main(String[] args) throws IOException {
    
    
        /*创建一个客户端,会抛出异常,本地回环IP,端口号9999*/
        Socket client = new Socket("localhost", 9999);
        System.out.println("已连接");
        /*获取一个输出流,向服务器发送一个消息*/
        OutputStream outputStream = client.getOutputStream();
        outputStream.write("服务器,你好!".getBytes());
        /*获取一个输入流,接收来自服务器得消息*/
        InputStream inputStream = client.getInputStream();
        byte[] bytes = new byte[1024];
        int length = inputStream.read(bytes);
        System.out.println(new String(bytes, 0, length));
        /*关闭输入输出流和socket*/
        outputStream.close();
        inputStream.close();
        client.close();
    }
}

服务器

工作过程

服务器程序的工作过程包含以下四个基本步骤

**1、调用ServerSocket(int port):**创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。

**2、调用accept():**监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。

**3、调用Socket类对象的getOutputStream()和getInputStream():**获取输入输出流,开始网络数据的发送和接收。

**4、关闭ServerSocket和Socket对象:**客户端访问结束,关闭通信套接字。

创建服务器

服务器建立ServerSocket对象,ServerSocket对象负责等待客户端请求建立套接字连接,类似于邮局某个窗口的业务员。也就是说,**服务器必须事先建立一个等待客户请求建立套接字连接的ServerSocket对象,**所谓的“接收”客户端的套接字请求,就是accept()方法会返回一个Socket对象。

代码示例——建立服务器

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

public class Server {
    
    
    /*这是一个程序入口*/
    public static void main(String[] args) throws IOException {
    
    
        /*创建一个服务器端*/
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("等待客户端连接...");
        /*监听客户端*/
        Socket server = serverSocket.accept();
        System.out.println("已连接");
        /*接收客户端的消息*/
        InputStream inputStream = server.getInputStream();
        byte[] bytes = new byte[1024];
        int length = inputStream.read(bytes);
        System.out.println(new String(bytes, 0, length));
        /*向客户端发送消息*/
        OutputStream outputStream = server.getOutputStream();
        outputStream.write("客户端,你好!".getBytes());
        /*关闭输入输出流服务器*/
        inputStream.close();
        outputStream.close();
        server.close();
        serverSocket.close();
    }
}

TCP实现双方连续交互

代码示例——服务器与客户端的连续交互——服务器

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class ServerDemo1 {
    
    
    /*这是一个程序入口*/
    public static void main(String[] args) throws IOException {
    
    
        /*创建一个服务器,保持持续开启不断开*/
        ServerSocket serverSocket = new ServerSocket(9898);
        System.out.println("等待客户端连接.....");
        /*监听客户端连接*/
        Socket server = serverSocket.accept();
        System.out.println("客户端连接成功!");
        /*创建输入输出流*/
        OutputStream outputStream = null;
        InputStream inputStream = null;
        Scanner data = new Scanner(System.in);
        while(true){
    
    
            inputStream = server.getInputStream();
            byte[] bytes = new byte[1024];
            int length = inputStream.read(bytes);
            System.out.println("小客:"+new String(bytes,0,length));

            outputStream = server.getOutputStream();
            String msg = data.next();
            outputStream.write(msg.getBytes());
        }
    }
}

代码示例——服务器与客户端的连续交互——客户端

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class ClientDemo1 {
    
    
    /*这是一个程序入口*/
    public static void main(String[] args) throws IOException {
    
    
        /*创建一个客户端*/
        Socket client = new Socket("127.0.0.1", 9898);
        System.out.println("服务器连接成功!");
        /*创建输入输出流*/
        OutputStream outputStream = null;
        InputStream inputStream = null;
        System.out.println("请输入您想询问小服的问题:");
        Scanner data = new Scanner(System.in);
        while (true) {
    
    
            outputStream = client.getOutputStream();
            String msg = data.next();
            outputStream.write(msg.getBytes());
            if (msg.equals("再见")){
    
    
                break;
            }
            inputStream = client.getInputStream();
            byte[] bytes = new byte[1024];
            int length = inputStream.read(bytes);
            System.out.println("小服:" + new String(bytes,0,length));

        }
        outputStream.close();
        client.close();
    }
}

UDP网络通信

概述

1、类 DatagramSocket 和 DatagramPacket 实现了基于UDP协议网络程序。

2、UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以送达。

3、DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。

4、UDP协议中每个数据报都给出了完整的地址信息,因此无法建立发送方和接收方的连接。

5、UDP网络通信流程

(1)DatagramSocket 与 DatagramPacket;

(2)建立发送端和接收端;

(3)建立数据包;

(4)调用 Socket 的发送、接收方法;

(5)关闭 Socket。

6、发送端和接收端是两个独立运行的程序。

实现UDP网络通信

发送端

import java.io.IOException;
import java.net.*;

/*发送端*/
public class Send {
    
    
    /*这是一个程序入口*/
    public static void main(String[] args) throws IOException {
    
    
        /*创建发送数据包的套接字*/
        DatagramSocket socket = new DatagramSocket();
        /*获取要发送的东西的字节数组*/
        byte[] bytes = "接收端,你好!".getBytes();
        /*
        * 创建传送数据报的包,
        * 指定一个InetAddress对象的IP地址InetAddress.getByName("127.0.0.1"),
        * 和端口号9009
        */
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length,
                InetAddress.getByName("127.0.0.1"),9009);

        /*使用DatagramSocket发送*/
        socket.send(packet);
        /*关闭套接字*/
        socket.close();
    }
}

接收端

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

public class Receive {
    
    
    /*这是一个程序入口*/
    public static void main(String[] args) throws IOException {
    
    
        /*创建接收数据包的套接字,指定端口号9009(指定监听的端口)*/
        DatagramSocket socket = new DatagramSocket(9009);
        /*创建一个装数据的字节数组*/
        byte[] bytes = new byte[1024];
        /*
        * 创建一个接收数据报的包
        * DatagramPacket(byte[] buf, int length)
        * 构造一个 DatagramPacket用于接收长度的数据包 length
        */
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
        /*使用DatagramSocket接收*/
        socket.receive(packet);
        /*将接收到包里数据报转化为字符串并输出*/
        String msg = new String(packet.getData(), 0, packet.getLength());
        System.out.println("发送端:" + msg);
        socket.close();
    }
}

UDP实现双方连续交互

所谓的发送端:(因为两端都是独立的程序)

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class SendDemo {
    
    
    /*这是一个程序入口*/
    public static void main(String[] args) throws IOException {
    
    
        /*创建互相通信的Socket*/
        DatagramSocket socket = new DatagramSocket(6666);

        System.out.println("已完成连接...请输入");
        Scanner data = new Scanner(System.in);
        while(true){
    
    
            /*发送消息*/
            String msgSend = data.next();
            byte[] bytes = msgSend.getBytes();
            DatagramPacket packetSend = new DatagramPacket(bytes,0, bytes.length,
                    InetAddress.getByName("127.0.0.1"), 5656);
            socket.send(packetSend);
            if (msgSend.equals("再见")){
    
    
                break;
            }
            /*接收消息*/
            byte[] bytes1 = new byte[1024];
            DatagramPacket packetReceive = new DatagramPacket(bytes1, 0,bytes1.length);
            socket.receive(packetReceive);
            String msgReceive = new String(packetReceive.getData(),0,packetReceive.getLength());
            System.out.println("白云:"+msgReceive);
        }
        socket.close();
    }
}

所谓的接收端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class ReceiveDemo {
    
    
    /*这是一个程序入口*/
    public static void main(String[] args) throws IOException {
    
    
        DatagramSocket socket = new DatagramSocket(5656);

        Scanner data = new Scanner(System.in);
        while(true){
    
    
            /*接收消息*/
            byte[] bytes = new byte[1024];
            DatagramPacket packetReceive = new DatagramPacket(bytes,0,bytes.length);
            socket.receive(packetReceive);
            String msgReceive = new String(packetReceive.getData(), 0, packetReceive.getLength());
            System.out.println("黑土:" + msgReceive);
            /*发送消息*/
            String msgSend = data.next();
            byte[] bytes1 = msgSend.getBytes();
            DatagramPacket packetSend = new DatagramPacket(bytes1,0, bytes1.length,
                    InetAddress.getByName("localhost"), 6666);
            socket.send(packetSend);
            if (msgSend.equals("再见")){
    
    
                break;
            }
        }
        socket.close();
    }
}

猜你喜欢

转载自blog.csdn.net/Lotus_dong/article/details/110978284