详解JAVA Socket

简介: 详解JAVA Socket

1.概述

什么是网络通信:

就像打电话一样,两点间要通信,两点间就必须有连接,为了实现任意两个节点之间的通信,我们就必须采取手段将所有节点连接起来,形成了一个巨大的拓扑结构,这就是计算机网络,节点间利用这个网络进行数据传输,就是网络通信。

什么是TCP协议:

节点间利用计算机网络进行通信时,难免会出现丢失、乱序,或者网络故障,数据直接就传输不到等情况,所以会存在一些规则用来保证通信的可靠,TCP协议就是一种用来进行可靠通信的规则。TCP协议提供了一套机制来解决数据丢失、乱序、网络故障等异常情况。


博主之前有一篇博文详细介绍了TCP,感兴趣的小伙伴可以移步看一下:

详解TCP__BugMan的博客-CSDN博客

什么是socket:

很明显作为开发BS架构应用的主流语言,JAVA也是需要网络通信的,Socket就是JAVA网络通信的核心。可以理解为一个Socket就是一条TCP连接,,Socket是对TCP/IP通信过程的一个抽象,它将TCP/IP里面复杂的通信逻辑进行 封装,对用户来说,只要通过一组简单的API就可以实现网络的连接和通信。

2.使用

服务端:

import java.io.*;
import java.net.*;
 
public class Server {
    public static void main(String[] args) {
        try {
            // 创建ServerSocket对象,监听端口号为8888
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("Server started. Waiting for client...");
 
            // 接受客户端连接请求
            Socket socket = serverSocket.accept();
            System.out.println("Client connected: " + socket.getInetAddress().getHostAddress());
 
            // 获取输入流和输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
 
            // 接收客户端发送的数据
            String clientMessage = reader.readLine();
            System.out.println("Received from client: " + clientMessage);
 
            // 发送响应给客户端
            String response = "Hello, client!";
            writer.println(response);
            System.out.println("Sent to client: " + response);
 
            // 关闭连接
            socket.close();
            serverSocket.close();
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户端:

import java.io.*;
import java.net.*;
 
public class Client {
    public static void main(String[] args) {
        try {
            // 创建Socket对象,连接服务器的IP地址和端口号
            Socket socket = new Socket("localhost", 8888);
 
            // 获取输入流和输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
 
            // 发送数据给服务器
            String message = "Hello, server!";
            writer.println(message);
            System.out.println("Sent to server: " + message);
 
            // 接收服务器响应
            String serverResponse = reader.readLine();
            System.out.println("Received from server: " + serverResponse);
 
            // 关闭连接
            socket.close();
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.使用场景

3.1.web server中的网络通信

首先实际开发中很少会需要开发去手写网络通信,网络通信作为一个基础模块,web server,即常用的tomcat、netty等web服务器已经帮开发人员实现了网络通信,从而让开发人员更加专注于业务的开发。


tomcat底层就是使用的socket来进行网络通信,tomcat启动后默认会去8080端口监听,每进来一个新的client端的请求就会用一个socket去接收、处理。如果是老的client端的话会用老的socket来处理请求。也就是说一个client端对应一个socket。


3.2.长连接

每个TCP连接都需要分配一定的内存用于存储连接的状态信息、缓冲区以及其他相关数据。这些信息包括套接字描述符、接收和发送缓冲区、TCP状态等。TCP连接越多,服务器需要分配的内存也会增加,所以能保持的TCP连接的条数是有上限的。


为了保证其它TCP连接能被即使连接进来,Tomcat一类的web server在处理socket时策略很保守,不会让TCP一直开启,即不会让TCP一直保持长连接,在一定时间内没有收到client端的请求后会自动关闭TCP连接。


但我们知道建立TCP连接是一个很重的操作,所以有时候我们希望有些TCP连接可以一直打开,这时候就可以用到长连接的思想。


长连接是HTTP 1.2推出的标准,Tomcat实现了该标准。实现的办法很简单,将要保持长连接的TCP(Socket),交给一条线程,让线程一直活着就行。如果要实现长连接可以参照这个思路。


3.3.性能问题

socket会存在两方面的性能问题:


1.大量时间可能会被浪费在读IO上


accept的socket并不知道其数据包是否已经收完,很可能出现因为数据包没有收完,还需要阻塞在原地等待IO继续收数据包的情况,本来分过来的CPU时间片是希望当前线程向下执行代码,结果用去继续IO收数据包去了,IO操作对于CPU而言很慢,时间片的利用率会很低,耗时会很严重,这也是为什么JAVA后面推出了NIO的原因。


2.单端口读写的话会存在性能瓶颈


由于一个ServerSocket只能监听一个指定的端口,所以当我们在服务端只有一个端口来进行IO的时候,必然会存在性能瓶颈。因为IO的本质就是向某些内存中进行数据的读写,这些内存是专门用来进行IO的。如果只是用了一个端口,那么就只是用了这些内存中的一小块儿,可以想象,很容易就会被打满,导致IO阻塞。


tomcat启动后监听8080端口,就是用的单个端口进行IO,就会存在这一方面的问题。


为了克服这个问题,一种常见的方法是使用负载均衡和多线程技术。服务器可以通过负载均衡将连接分布到多个监听端口上,并使用多线程或线程池来处理连接和读写操作。这样可以提高并发处理能力和吞吐量,减轻单个端口的压力。


以上两个性能问题都是在实际开发中值得注意,可以进行性能优化的点。

目录
相关文章
|
1月前
|
Java 流计算
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
35 1
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
|
16天前
|
Java
[Java]Socket套接字(网络编程入门)
本文介绍了基于Java Socket实现的一对一和多对多聊天模式。一对一模式通过Server和Client类实现简单的消息收发;多对多模式则通过Server类维护客户端集合,并使用多线程实现实时消息广播。文章旨在帮助读者理解Socket的基本原理和应用。
15 1
|
1月前
|
网络协议 安全 Java
Java Socket原理
Java Socket原理是指在Java中通过Socket实现的网络通信的基础理论与机制。Socket是网络中不同设备间通信的一种标准方式,它允许应用程序之间通过TCP/IP等协议进行数据交换。在Java中,利用Socket编程可以方便地创建客户端与服务器端应用,实现跨网络的数据传输功能,是互联网软件开发中的重要技术之一。它支持多种通信模式,如可靠的流式套接字(TCP)和数据报式套接字(UDP)。
|
4月前
|
Java
如何在Java中实现多线程的Socket服务器?
在Java中,多线程Socket服务器能同时处理多个客户端连接以提升并发性能。示例代码展示了如何创建此类服务器:监听指定端口,并为每个新连接启动一个`ClientHandler`线程进行通信处理。使用线程池管理这些线程,提高了效率。`ClientHandler`读取客户端消息并响应,支持简单的文本交互,如发送欢迎信息及处理退出命令。
|
4月前
|
网络协议 安全 Java
Java中的网络编程:Socket编程详解
Java中的网络编程:Socket编程详解
|
4月前
|
Java API 开发者
Java中的Socket编程与应用
Java中的Socket编程与应用
|
4月前
|
网络协议 安全 Java
Java中的网络编程:Socket编程详解
Java中的网络编程:Socket编程详解
|
4月前
|
Java API 开发者
Java中的Socket编程与应用
Java中的Socket编程与应用
|
4月前
|
网络协议 Java
如何在Java中使用Socket编程实现TCP连接?
在Java中,通过Socket编程实现TCP连接非常常见。以下演示了基本的TCP通信流程,可根据具体需求进行扩展。
249 0
|
4月前
|
Java 数据格式
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
82 0
下一篇
无影云桌面