Java网络编程(TCP)

1.概述

Java网络编程是利用Java语言进行网络通信应用程序开发的过程。它主要基于TCP/IP协议栈,支持Socket编程,包括流式Socket(TCP)和数据报Socket(UDP)。通过Socket,程序可以创建服务器端或客户端,实现网络上的数据传输与交互。Java的网络编程接口简洁且功能强大,提供了InetAddress类用于处理IP地址,ServerSocket和Socket类分别用于服务器和客户端的连接建立,以及InputStream和OutputStream类来读写数据,还有通过多线程机制可以实现高效地处理并发连接。

2.网络通信协议

要使计算机连成的网络能够互通信息,需要对数据传输速率、传输代码、代码结构、传输控制步骤、出错控制等制定一组标准,这一组共同遵守的通信标准就是网络通信协议,不同的计算机之间必须使用相同的通讯协议才能进行通信。

​ 七层模型,也称为OSI(Open System Interconnection)参考模型,是国际标准化组织(ISO)制定的一个用于计算机或通讯系统间互联的标准体系。它是一个七层的、抽象的模型体,不仅包括一系列抽象的术语或概念,也包括具体的协议。 在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 应用层

​应用程序之间如何相互传递报文,比如HTTP协议,FTP协议

  • 传输层

传输层的作用是为两台主机之间的"应用进程"提供端到端的逻辑通信,比如TCP协议

  • 网络层互联层

网络层互联层提供了主机到主机的通信,将传输层产生的数据包封装成分组数据包发送到目标主机,并提供路由选择能力. IP协议是网络层的主要协议,TCP和UDP都是用IP协议作为网络层协议.这一层的主要作用是给包加上源地址和目标地址,将数据包传送到目标地址.

  • 网络访问层

网络访问层也可以称为网络接口层,以太网,WIFI,蓝牙就是工作在这一层,网络访问层提供了主机连接到物理网络需要的硬件和相关协议

3.网络协议(TCP)

  • TCP:传输控制协议 (Transmission Control Protocol)。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。

    在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。

    • 三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
      • 第一次握手,客户端向服务器端发出连接请求,等待服务器确认。
      • 第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。
      • 第三次握手,客户端再次向服务器端发送确认信息,确认连接。整个交互过程如下图所示。
        在这里插入图片描述

完成三次握手,连接建立后,客户端和服务器就可以开始进行数据传输了。由于这种面向连接的特性,TCP协议可以保证传输数据的安全,所以应用十分广泛,例如下载文件、浏览网页等。

使用TCP协议实现通信,需要使用流式套接字。即客户端采用socket,而服务器端采用ServerSocket来完成通信的方式

​ 此时实现服务器端与客户端通信的思路:
在这里插入图片描述
其中,处理服务器端通信的ServerSocket类,其常见构造如下:

构造方法说明
ServerSocket()创建一个ServerSocket对象
ServerSocket(int port)创建一个ServerSocket对象,并绑定到指定端口

ServerSocket常用方法如下:

常用方法说明
Socket accept()侦听并接收到此ServerSocket的连接,此方法在连接传入之前一直阻塞
void close()使服务器释放占用的资源,并断开所有与客户端的连接
InetAddress getInetAddress()返回当前服务器绑定的IP地址信息
处理客户端通信的Socket类:

Socket的构造共有9种,这里介绍2种常用的构造方法:

构造方法说明
Socket(String host, int port)向host主机的port端口发起连接请求
Socket(String host,int port,InetAddress localAddr,int localPort)向host主机的port端口发起连接请求,发起请求的计算机为localAddr,端口为localPort

注意:InetAddress类表示互联网协议地址,包含IP地址,实际上就是java对IP地址的封装。

Socket的常用方法:

常用方法说明
InetAddress getInetAddress()返回与当前Socket对象关联的InetAddress对象
void shutdownInput()此套接字的输入流置于“流的末尾”
void shutdownOutput()禁用此套接字的输出流
InputStream getInputStream()返回当前Socket对象关联的InputStream对象,它是服务器端向客户端发送回来的数据流.
OutputStream getOutputStream()返回当前Socket 对象关联的OutputStream对象,它是客户端想服务器端发送的数据流
void close()关闭该socket建立的连接

3.简单的TCP网络程序

  1. 【服务端】启动,创建ServerSocket对象,等待连接。
  2. 【客户端】启动,创建Socket对象,请求连接。
  3. 【服务端】接收连接,调用accept方法,并返回一个Socket对象。
  4. 【客户端】Socket对象,获取OutputStream,向服务端写出数据。
  5. 【服务端】Scoket对象,获取InputStream,读取客户端发送的数据。

到此,客户端向服务端发送数据成功。

在这里插入图片描述

自此,服务端向客户端回写数据。

  1. 【服务端】Socket对象,获取OutputStream,向客户端回写数据。
  2. 【客户端】Scoket对象,获取InputStream,解析回写数据。
  3. 【客户端】释放资源,断开连接。

运用字节缓冲流让客户端和服务器各传一句话:

服务端:

public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            serverSocket = new ServerSocket(8888);//创建一个端口号为“8888”的ServerSocket对象
            System.out.println("服务器启动!!!");
            //运用serverSocket.accept()等待客户端连接,然后再把连接上的客户端的信息传入socke中
            socket = serverSocket.accept();
            System.out.println("客户端已连接!!!");

            //有客户端连接上之后先读取客户端发来的消息
            //运用字节缓冲流
            byte[] bytes = new byte[1024];
            bufferedInputStream = new BufferedInputStream(socket.getInputStream());
            int len = bufferedInputStream.read(bytes);
            String str = new String(bytes, 0, len);
            System.out.println("客户端说:" + str);

            //读取后运用输出流给客户端发送消息
            bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
            bufferedOutputStream.write("客户端,大样".getBytes());
            //消息发送之后进行刷新
            bufferedOutputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                bufferedOutputStream.close();
                bufferedInputStream.close();
                socket.close();
                serverSocket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

客户端:

public class Client {
    public static void main(String[] args) {
        Socket socket=null;
        BufferedInputStream bufferedInputStream=null;
        BufferedOutputStream bufferedOutputStream=null;

        try {
            //先连接服务器,IP地址"localhost"即为本机,“8888”为端口号
            socket=new Socket("localhost",8888);
            //连接上服务器直接向服务器发送消息
            bufferedOutputStream=new BufferedOutputStream(socket.getOutputStream());
            bufferedOutputStream.write("服务器,小样".getBytes());
            bufferedOutputStream.flush();

            //接收服务端发送来的消息
            System.out.print("服务器说:");
            bufferedInputStream=new BufferedInputStream(socket.getInputStream());
            int len;
            byte[] bytes=new byte[1024];
            String str="";
            int len = bufferedInputStream.read(bytes);
            String str = new String(bytes, 0, len);
            System.out.println(str);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                bufferedOutputStream.close();
                bufferedInputStream.close();
                socket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
    }
}

运行结果:
服务器:
在这里插入图片描述
客户端:
在这里插入图片描述

运用字符缓冲流让客户端和服务器一直聊天:

服务端:

public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedReader br = null;
        BufferedWriter bw = null;
        Scanner input = new Scanner(System.in);
        try {
            serverSocket = new ServerSocket(8888);
            System.out.println("服务器已启动!!!");
            socket = serverSocket.accept();
            System.out.println("客户端已连接!!!");
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            while (true) {
                String str = br.readLine();
                System.out.println("客户端说:" + str);

                bw.write(input.next());
                bw.newLine();
                bw.flush();
                if (str.equals("666")) {
                    break;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                bw.close();
                br.close();
                socket.close();
                serverSocket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

客户端:

public class Client {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Socket socket = null;
        BufferedWriter bw = null;
        BufferedReader br=null;
        try {
            socket = new Socket("localhost", 8888);
            System.out.println("已成功连接服务器!!!");
            System.out.print("向服务器发送消息:");
            bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String str;
            while (true) {
                bw.write(input.next());
                bw.newLine();
                bw.flush();

                str=br.readLine();
                System.out.println("服务器说:"+str);
                if(str.equals("666")){
                    break;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                bw.close();
                socket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

服务端:
在这里插入图片描述

客户端:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值